geoveil_mp

Crates.iogeoveil_mp
lib.rsgeoveil_mp
version0.1.1
created_at2026-01-21 14:23:13.075091+00
updated_at2026-01-21 14:23:13.075091+00
descriptionHigh-performance GNSS multipath analysis library with support for RINEX v2/v3/v4, SP3 precise orbits, and multi-constellation processing
homepagehttps://github.com/miluta7/geoveil-mp
repositoryhttps://github.com/miluta7/geoveil-mp
max_upload_size
id2059338
size384,592
MiluΘ›Δƒ FlueraΘ™ (miluta7)

documentation

https://docs.rs/geoveil-mp

README

GeoVeil-MP: GNSS Multipath Analysis Library

Crates.io PyPI Rust Python License: MIT CI/CD

A high-performance Rust library for GNSS multipath analysis with Python bindings. Part of the GeoVeil suite for GNSS signal quality analysis.

Features

  • πŸ›°οΈ RINEX Support: Full support for RINEX v2.xx, v3.xx, and v4.xx observation files
  • 🌍 Multi-GNSS: GPS, GLONASS, Galileo, BeiDou, QZSS, NavIC/IRNSS, SBAS
  • πŸ“‘ Navigation Data:
    • Broadcast ephemerides (Keplerian elements)
    • GLONASS state vector propagation (4th-order Runge-Kutta)
    • SP3 precise orbit interpolation (Neville's algorithm)
  • πŸ“Š Multipath Analysis: Code multipath estimation using linear combinations
  • ⚑ Cycle Slip Detection: Ionospheric residuals and code-phase combinations
  • πŸ“ Position Estimation: Least squares SPP with DOP calculation
  • 🎨 Visualization: R plotting integration for publication-quality figures
  • πŸš€ High Performance: Parallel processing with Rayon, memory-mapped I/O
  • 🐍 Python Bindings: Full Python API via PyO3

Installation

Python (PyPI)

pip install geoveil-mp

Rust (Cargo)

[dependencies]
geoveil_mp = "0.1"

Or with all features:

[dependencies]
geoveil_mp = { version = "0.1", features = ["full"] }

From Source

# Clone the repository
git clone https://github.com/miluta7/geoveil-mp.git
cd geoveil-mp

# Build Rust library
cargo build --release

# Build Python wheel
pip install maturin
maturin develop --release --features python

Quick Start

Python Usage

import geoveil_mp as gm

# Read RINEX observation file
obs = gm.read_rinex_obs("observation.24o")
print(f"Loaded {obs.num_epochs} epochs, {obs.num_satellites} satellites")

# Read SP3 precise ephemeris (optional, for accurate elevations)
sp3 = gm.read_sp3("ephemeris.sp3")

# Create analyzer with elevation cutoff
analyzer = gm.MultipathAnalyzer(
    obs,
    elevation_cutoff=10.0,
    systems=["G", "E", "R", "C"]  # GPS, Galileo, GLONASS, BeiDou
)

# Run multipath analysis
results = analyzer.analyze()

# Compute satellite elevations from SP3
if sp3 and obs.approx_position:
    computed, failed = results.compute_elevations(sp3, obs.approx_position)
    print(f"Elevations: {computed} computed, {failed} failed")

# Access results
print(f"Total estimates: {results.total_estimates()}")
print(f"Cycle slips detected: {results.total_cycle_slips()}")

# Print statistics by signal
for stat in results.statistics:
    print(f"{stat.signal}: RMS={stat.rms:.4f}m, Count={stat.count}")

# Export to CSV
import pandas as pd
data = [{
    'satellite': e.satellite,
    'epoch': e.epoch,
    'mp_value': e.mp_value,
    'elevation': e.elevation,
    'signal': e.signal
} for e in results.estimates]
df = pd.DataFrame(data)
df.to_csv("multipath_results.csv", index=False)

Rust Usage

use geoveil_mp::{
    prelude::*,
    RinexObsReader, Sp3Reader,
    navigation::SatellitePositionProvider,
};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Read RINEX observation file
    let obs_data = RinexObsReader::new().read("observation.24o")?;
    
    // Read SP3 precise ephemeris
    let sp3_data = Sp3Reader::read("ephemeris.sp3")?;
    
    // Configure analysis
    let config = AnalysisConfig::default()
        .with_elevation_cutoff(10.0)
        .with_systems(&["G", "E", "R", "C"]);
    
    // Run multipath analysis
    let analyzer = MultipathAnalyzer::new(obs_data, config);
    let results = analyzer.analyze()?;
    
    // Export results
    results.to_csv("results.csv")?;
    
    // Print statistics
    for (signal, stats) in &results.statistics {
        println!("{}: RMS={:.4}m, Count={}", signal, stats.rms, stats.count);
    }
    
    Ok(())
}

CLI Usage

# Analyze RINEX file with SP3 orbits
geoveil-mp analyze --obs observation.24o --sp3 ephemeris.sp3 --csv results.csv

# Get file information
geoveil-mp info observation.24o

# Estimate position from pseudoranges
geoveil-mp position --obs observation.24o --nav navigation.24n

Multipath Estimation

The code multipath is estimated using the linear combination:

$$MP_1 = R_1 - \left(1+\frac{2}{\alpha - 1}\right)\Phi_1 + \left(\frac{2}{\alpha - 1}\right)\Phi_2$$

where:

  • $R_1$ is the code observation on frequency 1
  • $\Phi_1, \Phi_2$ are phase observations on frequencies 1 and 2
  • $\alpha = f_1^2/f_2^2$ is the frequency ratio squared

This combination eliminates ionospheric delay and geometry, leaving only code multipath, code noise, and ambiguity-related biases.

Supported GNSS Systems

System Code Frequencies Navigation
GPS G L1, L2, L5 Keplerian
GLONASS R G1, G2, G3 State Vector (RK4)
Galileo E E1, E5a, E5b, E6 Keplerian
BeiDou C B1I, B1C, B2a, B2b, B3I Keplerian
QZSS J L1, L2, L5, L6 Keplerian
NavIC I L5, S, L1 Keplerian
SBAS S L1, L5 -

Data Sources

SP3 Precise Orbits (No Authentication Required)

ESA:  http://navigation-office.esa.int/products/gnss-products/{week}/
GFZ:  https://igs.bkg.bund.de/root_ftp/IGS/products/mgex/{week}/
CODE: https://igs.bkg.bund.de/root_ftp/IGS/products/mgex/{week}/

Broadcast Navigation

BKG:  https://igs.bkg.bund.de/root_ftp/IGS/BRDC/{year}/{doy}/
IGN:  https://igs.ign.fr/pub/igs/data/{year}/{doy}/

Python API Reference

Classes

Class Description
GnssSystem GNSS constellation identifier (G, R, E, C, J, I, S)
Satellite Satellite PRN identifier (e.g., "G01", "E11")
Epoch Time representation with GPS/Julian conversions
Ecef Earth-Centered Earth-Fixed coordinates
Geodetic Latitude/Longitude/Height coordinates
RinexObsData RINEX observation data container
Sp3Data SP3 precise orbit data container
MultipathAnalyzer Main multipath analysis engine
AnalysisResults Analysis results container

Functions

Function Description
read_rinex_obs(path) Read RINEX observation file
read_rinex_obs_bytes(data, filename) Read RINEX from bytes
read_sp3(path) Read SP3 precise orbit file
get_frequency(system, band, fcn) Get signal frequency (Hz)
get_wavelength(system, band, fcn) Get signal wavelength (m)
calculate_azel(receiver, satellite) Compute azimuth/elevation
compute_elevation(sp3, receiver, sat, epoch) Compute elevation from SP3
version() Get library version

Constants

Constant Value Description
SPEED_OF_LIGHT 299792458.0 Speed of light (m/s)
GM_WGS84 3.986005e14 Earth gravitational parameter (mΒ³/sΒ²)
EARTH_RADIUS 6378137.0 WGS84 Earth radius (m)

Architecture

geoveil_mp/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ lib.rs              # Library entry point
β”‚   β”œβ”€β”€ python.rs           # Python bindings (PyO3)
β”‚   β”œβ”€β”€ rinex/              # RINEX parsing
β”‚   β”‚   β”œβ”€β”€ types.rs        # Data structures
β”‚   β”‚   └── obs_reader.rs   # Observation file reader
β”‚   β”œβ”€β”€ navigation/         # Ephemeris handling
β”‚   β”‚   β”œβ”€β”€ types.rs        # Ephemeris types
β”‚   β”‚   β”œβ”€β”€ kepler2ecef.rs  # Keplerian to ECEF
β”‚   β”‚   β”œβ”€β”€ glonass.rs      # GLONASS Runge-Kutta
β”‚   β”‚   └── sp3.rs          # SP3 Neville interpolation
β”‚   β”œβ”€β”€ analysis/           # Analysis algorithms
β”‚   β”‚   β”œβ”€β”€ multipath.rs    # Multipath estimation
β”‚   β”‚   β”œβ”€β”€ cycle_slip.rs   # Cycle slip detection
β”‚   β”‚   └── position.rs     # Position estimation
β”‚   β”œβ”€β”€ plotting/           # R integration
β”‚   └── utils/              # Utilities
β”‚       β”œβ”€β”€ constants.rs    # Physical constants
β”‚       β”œβ”€β”€ coordinates.rs  # Coordinate transforms
β”‚       β”œβ”€β”€ time.rs         # Time handling
β”‚       └── error.rs        # Error types
β”œβ”€β”€ examples/
β”œβ”€β”€ tests/
└── r_scripts/              # R plotting scripts

Performance

Benchmarks on a typical 24-hour multi-GNSS RINEX file (~100MB):

Operation Time Notes
Read RINEX 3.05 ~500ms Memory-mapped I/O
Read SP3 ~50ms Neville interpolation ready
Multipath analysis ~200ms Parallel processing
Position estimation ~2s All epochs

Related Projects

References

  • RINEX 4.02 Specification (IGS/RTCM)
  • GPS Interface Control Document (IS-GPS-200)
  • GLONASS Interface Control Document (ICD-GLONASS)
  • Galileo OS-SDD (Open Service Signal-in-Space ICD)
  • IGS Multi-GNSS Experiment (MGEX)

License

MIT License - see LICENSE file for details.

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

Changelog

See CHANGELOG.md for version history.

Commit count: 7

cargo fmt