Skip to main content

A tool to parse, check and resample Rinex files

Project description

RinexParser

Python toolkit to parse, analyze, and resample RINEX observation files. Supports RINEX versions 2 and 3.

Features

  • Parse RINEX 2 and RINEX 3 observation files
  • Resample/thin epochs to specified intervals
  • Generate quality statistics (rinstat reports)
  • Support for gzip-compressed files (.gz)
  • Command-line interface for batch processing
  • Python API for programmatic access

Installation

pip install RinexParser

The rxp command-line tool will be available after installation.

Command-Line Usage

Resample RINEX files

Thin epochs to a specified interval (e.g., 30 seconds):

# Single file
rxp --resample 30 station.rnx

# Multiple files (creates *_resample.rnx for each)
rxp --resample 30 *.rnx

# Compressed files
rxp --resample 30 station.rnx.gz

# Show output while writing files
rxp --resample 30 *.rnx --show-output

Output: station_resample.rnx

Output filename formats

Use special output format specifiers to automatically generate filenames:

# Standard RINEX 3 long name format
rxp --resample 30 -o "::RX3::" station.rnx

# With country code (Austria)
rxp --resample 30 -o "::RX3-cAUT::" station.rnx

# Full format with country and station name (when implemented)
rxp --resample 30 -o "::RX3-cAUT-sGRAZ::" station.rnx

The output format specifiers work as follows:

  • ::RX3:: - Converts to RINEX 3 long name format (auto-extracts country from input filename if available)
  • ::RX3-cXXX:: - Converts to RINEX 3 long name with specified country code (e.g., cAUT for Austria, cDEU for Germany)
  • ::RX3-cXXX-sSTATION:: - RINEX 3 long name with country and station name (not yet implemented)

When not using special format specifiers, provide a standard output filename:

rxp --resample 30 -o output.rnx station.rnx

Generate Quality Statistics

Create rinstat reports:

# Text format
rxp --rinstat station.rnx
# Output: station_rinstat.txt

# JSON format
rxp --rinstat-json station.rnx
# Output: station_rinstat.json

# Multiple files
rxp --rinstat *.rnx.gz

Crop observations by time window

Extract observations from a specific time period:

# Crop with ISO format timestamps
rxp --crop-start 2026-01-20T00:00:00 --crop-end 2026-01-21T00:00:00 --resample 30 station.rnx

# Date only (uses full day)
rxp --crop-start 2026-01-20 --crop-end 2026-01-21 --resample 30 station.rnx

Filter satellite observations

Remove specific satellites or observation types:

# Remove specific satellites
rxp --filter-sat-pnr G01,R04,E12 --resample 30 station.rnx

# Remove entire satellite system (GPS, GLONASS, Galileo, etc.)
rxp --filter-sat-sys G,R --resample 30 station.rnx

# Remove observation types
rxp --filter-sat-obs G1C,R1C --resample 30 station.rnx

Update header fields using skeleton file

Use a skeleton file to copy header information (marker, receiver, antenna, observer details) to processed files:

# Apply skeleton header
rxp --skeleton skeleton.rnx --resample 30 station.rnx

# Skeleton can also set country code
rxp --skeleton skeleton.rnx -o output.rnx --resample 30 station.rnx

The skeleton file should contain valid RINEX header lines. Supported fields include:

  • MARKER NAME and MARKER NUMBER
  • REC # / TYPE / VERS (receiver info)
  • ANT # / TYPE (antenna info)
  • APPROX POSITION XYZ (station coordinates)
  • ANTENNA: DELTA H/E/N (antenna offsets)
  • OBSERVER / AGENCY
  • COMMENT (can include CountryCode=XX for automatic country detection)

Example skeleton file:

     3.04           OBSERVATION DATA    G (GPS)             RINEX VERSION / TYPE
My Marker Station                       MARKER NAME
123456                                  MARKER NUMBER
SWIFTNAV PiksiMulti                     REC # / TYPE / VERS
TrimbleChoke_MC2000                     ANT # / TYPE
 3771234.1234  3456789.5678   5123456.9 APPROX POSITION XYZ
        0.0000        0.0000        0.0000 ANTENNA: DELTA H/E/N
Observer Name                           OBSERVER / AGENCY
CountryCode=AUT                         COMMENT

Merge Multiple RINEX Files

Combine multiple RINEX files from the same station into a single continuous file:

# Merge multiple files (groups by 4-letter station code)
rxp --merge *.rnx

# Merge with resampling
rxp --resample 30 --merge *.rnx

# Merge multiple files with output format specifier
rxp --resample 30 --merge -o "::RX3-cAUT::" *.rnx

The merge operation:

  • Groups files by the 4-letter station code (first 4 characters of filename)
  • Sorts files chronologically
  • Combines headers and epochs into a single continuous file
  • Logs header changes between merged files as comments

Parallel Processing

Use multiple threads for faster batch processing:

# Process 4 files in parallel
rxp --resample 30 --threads 4 *.rnx

# Combine with merge for fast batch operations
rxp --resample 30 --merge --threads 4 *.rnx

Performance Profiling

Enable CPU profiling to analyze performance:

# Run with CPU profiling enabled
rxp --resample 30 --profile station.rnx

# Profiling results showing top 20 functions by execution time

Help reference

The help of rxp shows the following output:

usage: rxp [-h] [--resample SECONDS] [--rinstat] [--rinstat-json] [-o FILE] [-v] [--show-output] [--crop-start DATETIME] [--crop-end DATETIME]
           [--filter-sat-pnr FILTER_SAT_PNR] [--filter-sat-sys FILTER_SAT_SYS] [--filter-sat-obs FILTER_SAT_OBS] [-t SKELETON]
           [-m] [-n THREADS] [--profile] [--version]
           rinex_files [rinex_files ...]

RINEX observation file parser and processor

positional arguments:
  rinex_files           RINEX observation file(s) to process

options:
  -h, --help            show this help message and exit
  --resample SECONDS    Resample observations to specified interval (seconds)
  --rinstat             Generate RINSTAT quality report
  --rinstat-json        Generate RINSTAT quality report in JSON format
  -o, --output FILE     Output filename (auto-generated if not specified)
  -v, --verbose         Enable verbose logging
  --show-output         Print the generated output to console
  --crop-start DATETIME
                        Start time for cropping (ISO format: YYYY-MM-DD[[T]HH:MM:SS], YYYY-DOY)
  --crop-end DATETIME   End time for cropping (ISO format: YYYY-MM-DD[[T]HH:MM:SS], YYYY-DOY)
  --filter-sat-pnr FILTER_SAT_PNR
                        Remove satellites (G01,R04,E12,...)
  --filter-sat-sys FILTER_SAT_SYS
                        Remove satellite system (G,I,S) from epoch.
  --filter-sat-obs FILTER_SAT_OBS
                        Remove observation type (G1C,R1C,E8I,C6Q).
  -t, --skeleton SKELETON
                        Path to skeleton file to edit header
  -m, --merge           Merge multiple RINEX files
  -n, --threads THREADS
                        Number of threads to use
  --profile             Enable CPU profiling
  --version             Show version and exit

Python API

Basic Usage

from rinex_parser.obs_parser import RinexParser

# Parse RINEX file
parser = RinexParser(rinex_file="station.rnx", rinex_version=3)
parser.do_create_datadict()

rnx_parser = RinexParser(rinex_file=RINEX3_FILE, rinex_version=3, sampling=30)
rnx_parser.run()

out_file = os.path.join(
    os.path.dirname(input_file),
    rnx_parser.get_rx3_long()
)

# Output Rinex File
with open(out_file, "w") as rnx:
    logger.info(f"Write to file: {rnx_parser.get_rx3_long()}")
    rnx.write(rnx_parser.rinex_reader.header.to_rinex3())
    rnx.write("\n")
    rnx.write(rnx_parser.rinex_reader.to_rinex3())
    rnx.write("\n")
# Access parsed epochs (efficient __slots__ objects)
epochs = parser.rinex_reader.rinex_epochs
for epoch in epochs:
    print(f"Time: {epoch.timestamp}, Satellites: {len(epoch.satellites)}")

# Export to RINEX 3 format (includes header)
output = parser.rinex_reader.to_rinex3()
print(output)

There is an entry point that allows you to use it from the command line via the rxp command (see command-line usage above).

Notice

This code is currently under active development and is provided as-is. The author makes no warranties, express or implied, regarding the functionality, reliability, or safety of this code. By using this code, you assume all risks associated with its use. The author is not liable for any damages, loss of data, or other issues that may arise from the use of this code. Please use at your own discretion.

Resample/Thin Epochs

from rinex_parser.obs_parser import RinexParser

parser = RinexParser(rinex_file="station.rnx", rinex_version=3)
parser.do_create_datadict()

# Thin to 30-second intervals
parser.rinex_reader.do_thinning(30)

# Export resampled data
output = parser.rinex_reader.to_rinex3()
with open("station_30s.rnx", "w") as f:
    f.write(output)

Generate Quality Reports

from rinex_parser.obs_parser import RinexParser
from rinex_parser.obs_quality import RinexQuality

parser = RinexParser(rinex_file="station.rnx", rinex_version=3)
parser.do_create_datadict()

# Generate rinstat report (pass reader object directly)
quality = RinexQuality(rinex_format=parser.rinex_version)
report = quality.get_rinstat_out(parser.rinex_reader)
print(report)

# Get statistics as dictionary
stats_dict = quality.get_rinstat_as_dict(parser.rinex_reader)

Known Issues

  • Epoch dates are zero-padded in output
  • Some observation values may have different padding than input
  • Header field ordering may differ from input file

Requirements

  • Python 3.8+
  • pytz

License

GNU General Public License v3.0

Contributing

Contributions welcome! The codebase follows PEP 8 standards with comprehensive type hints and docstrings.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rinexparser-1.2.2.tar.gz (56.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

rinexparser-1.2.2-py3-none-any.whl (58.5 kB view details)

Uploaded Python 3

File details

Details for the file rinexparser-1.2.2.tar.gz.

File metadata

  • Download URL: rinexparser-1.2.2.tar.gz
  • Upload date:
  • Size: 56.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for rinexparser-1.2.2.tar.gz
Algorithm Hash digest
SHA256 ece748c28f5e9a7043a707840a0928059929ca7cd2ffe3aeda1ac66e1afac3ec
MD5 8e23f65c0770c58a8e634f9efb2bdd5a
BLAKE2b-256 68c150aa6a61f73630bd401fcaeef303780beaa553dec2a2df93d3fd44aeb1ec

See more details on using hashes here.

File details

Details for the file rinexparser-1.2.2-py3-none-any.whl.

File metadata

  • Download URL: rinexparser-1.2.2-py3-none-any.whl
  • Upload date:
  • Size: 58.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for rinexparser-1.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 940358b378c8ed5c43a9848f313df15f4bf3d8a135a9504a14c54956a528aace
MD5 442e3386be45f573924c809764f9dc91
BLAKE2b-256 ffde472d4df8227f981c5543b055c4fbd6c70e3afb2e04f841c140a40188b81b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page