Skip to main content
CN0 Signal Quality Chart

geoveil-cn0

High-performance GNSS signal quality analysis — Rust core, Python API

PyPI version PyPI downloads License: PolyForm Noncommercial Python 3.9+ Rust GitHub Stars


Analyze RINEX observation files to compute signal quality scores, detect threats (jamming, spoofing, interference), generate per-constellation statistics, and produce skyplot data. Used in production at Romanian national geodetic network (ROMPOS), precision agriculture, and GNSS security research.


Features

🛡️ Threat Detection

Jamming · Spoofing · Interference Three independent detectors Visibility-based spoofing (new in 0.3.8)

📊 Quality Scoring

Composite 0–100 score 5 weighted components A–F letter grade

🌍 6 Constellations

GPS · GLONASS · Galileo BeiDou · QZSS · NavIC Per-constellation stats

⚡ Rust Performance

0.14–2.6 s per 24 h file Zero Python dependencies ThreadPool-parallel batches

📡 RINEX Support

v2.x / v3.x / v4.x Broadcast navigation Visibility prediction

🔬 Full API

JSON export · Timeseries Skyplot data · Anomaly list Desktop GUI script included

Quality Score Breakdown
Threat Detection

Installation

pip install geoveil-cn0

No Rust toolchain required — pre-built wheels for Linux (x86_64 + ARM/piwheels), Windows, and macOS. Python 3.9–3.12.


Quick Start

from geoveil_cn0 import AnalysisConfig, CN0Analyzer

config = AnalysisConfig(
    min_elevation=10.0,          # mask angle, degrees
    time_bin_seconds=60,         # 1-minute bins
    anomaly_sensitivity=0.5,     # 0.0 = permissive, 1.0 = strict
    interference_threshold_db=6.0,
)

analyzer = CN0Analyzer(config)
result = analyzer.analyze_file("COST00ROU_R_20260980000_01D_30S_MO.rnx")

q = result.quality_score
print(f"Quality score : {q.overall:.1f} / 100  ({q.rating})")
print(f"Jamming       : {'DETECTED' if result.jamming_detected else 'clean'}")
print(f"Spoofing      : {'DETECTED' if result.spoofing_detected else 'clean'}")
print(f"Interference  : {'DETECTED' if result.interference_detected else 'clean'}")
print(f"Satellites    : {result.total_satellites} tracked")
print(f"Constellations: {', '.join(result.get_systems())}")

geoveil-cn0 reads plain RINEX. Decompress Hatanaka (.crx, .??d) and gzip files first, for example with the hatanaka package: hatanaka.decompress_on_disk("file.crx.gz").

Spoofing: visibility-based detection (new in 0.3.8)

# Requires navigation file for ephemeris comparison
result = analyzer.analyze_with_nav(
    "COST00ROU_R_20260408_0100_30S_MO.rnx",
    "BRDC00IGS_R_20260408_01D_MN.rnx",
)

if result.has_visibility_prediction:
    print(f"Confirmation rate: {result.visibility_confirmation_rate:.0f}%")
    print(f"Unexpected sats  : {result.visibility_mean_unexpected:.1f}")
    print(f"Missing sats     : {result.visibility_mean_missing:.1f}")

Architecture

flowchart LR
    A["RINEX obs\n.rnx / .??o"] --> C
    B["BRDC nav\n.nav/.rnx"] --> C
    C["CN0Analyzer\nRust core"] --> D["Quality Score\n0–100"]
    C --> E["Threat Flags\nJam/Spoof/Interf"]
    C --> F["Visibility\nPrediction"]
    C --> G["Timeseries\nCN0 per bin"]
    C --> H["Skyplot\nAz/El tracks"]
    D & E & F & G & H --> I["AnalysisResult\nJSON / Python API"]

Performance

Public IGS files from 31 December 2025, plain RINEX, one core of an Intel Xeon E5-2620 v3 (2014), median of three runs, min_elevation=10, 60 s bins:

File Size Epochs × sats analyze_file analyze_with_nav Peak memory
RINEX 2.11 · 24 h · 30 s · ZIMM (GPS) 5.4 MB 2,880 × 32 0.14 s 4.31 s 104 MB
RINEX 3.02 · 24 h · 30 s · BOR1 (6 GNSS) 19.4 MB 2,880 × 106 2.57 s 7.97 s 446 MB
RINEX 3.05 · 15 min · 1 Hz · BUCU 9.6 MB 900 × 44 0.99 s 2.62 s 201 MB
RINEX 3.05 · 1 h · 1 Hz · BUCU 39.9 MB 3,600 × 52 3.78 s 9.98 s 739 MB
RINEX 3.05 · 24 h · 1 Hz · BUCU 948.1 MB 86,400 × 127 129.1 s 263.8 s 14.2 GB

The analysis is single-threaded; CN0Analyzer is stateless, so a ThreadPoolExecutor over files scales with the cores available. analyze_with_nav adds visibility prediction from broadcast ephemeris.


Quality Score Components

The composite quality score (0–100, result.quality_score) is computed from five weighted components:

Component Weight Description
CN0 Quality 30% Mean signal strength: 0 at 30 dB-Hz, 100 at 45 dB-Hz
Availability 25% Satellites observed / satellites expected
Continuity 20% Absence of tracking gaps
Stability 15% Low CN0 standard deviation: 100 at 2 dB-Hz, 0 at 10 dB-Hz
Diversity 10% Constellations observed (4 = 100%)

Rating: A ≥ 90 · B ≥ 80 · C ≥ 70 · D ≥ 60 · F < 60. result.score and result.quality_grade report the same score.


Threat Detection

Threat Algorithm Default Threshold
Jamming Rapid CN0 drop rate >6 dB in <3 s
Spoofing Unexpected satellite ratio (BRDC ephemeris comparison) >40% ratio + >8 count + corroboration
Interference Sustained CN0 degradation >6 dB from baseline

Spoofing detection requires a navigation file (analyze_with_nav). The 0.3.8 algorithm compares observed satellites against ephemeris predictions — a high ratio of unexplained observations indicates signal replay attacks.


API Reference

AnalysisConfig

Parameter Type Default Description
min_elevation float 5.0 Mask angle in degrees
time_bin_seconds int 60 Seconds per analysis bin
systems list[str] all Constellations to analyze, e.g. ["G", "R", "E", "C"]
detect_anomalies bool True Run the anomaly detectors
anomaly_sensitivity float 0.5 Detection sensitivity 0–1
interference_threshold_db float 6.0 Interference trigger (dB)
spoofing_unexpected_threshold float 0.40 Fraction of unexpected satellites
spoofing_min_unexpected_count float 8 Minimum count to flag

CN0Analyzer

Method Description
analyze_file(obs_path) Analyze an observation file
analyze_with_nav(obs_path, nav_path) Also predict visibility from broadcast ephemeris (spoofing check, skyplot)

AnalysisResult — key members

Member Type Description
quality_score QualityScore overall, rating, cn0_quality, availability, continuity, stability, diversity
quality_grade str Letter A–F
jamming_detected / spoofing_detected / interference_detected bool Threat flags
mean_cn0, min_cn0, max_cn0 float CN0 statistics (dB-Hz)
total_epochs, total_satellites int File size in epochs and satellites
visibility_confirmation_rate float Percent of predicted satellites observed (with nav)
get_systems() list Constellations present
get_constellation_summary(name) dict Per-constellation CN0 and satellite counts
get_timeseries_data() dict hours, mean_cn0, satellite_count per epoch
get_skyplot_data() list Per-satellite azimuth, elevation and CN0 tracks (with nav)
get_anomalies() list Detected anomaly events
to_json() str Full result as JSON

Supported Formats

Input Extensions Notes
RINEX 2.x observation .??o, .obs
RINEX 3.x / 4.x observation .rnx, .obs Mixed observation files
RINEX navigation .rnx, .??n, .??p For analyze_with_nav

Compressed files (Hatanaka .crx/.??d, gzip, ZIP) must be decompressed first.


Website

miluta7.github.io/geoveil-cn0: live CN0 skyplot, per-constellation signal curves and benchmarks from real geoveil-cn0 output.


Live Demo

batch.geoveil-rinex.eu — the GeoVeil batch dashboard runs this library in production: CN0 quality scoring, threat detection, skyplots and heatmaps for every processed RINEX file, plus advanced multipath sessions (per-code MP RMS, cycle slips, SNR-residual wavelet spectra, Fresnel zones) and long-term trend monitoring on daily 30 s station data.


Batch Processing

For large-scale processing this library is wrapped by the GeoVeil batch system (FastAPI + Celery + MongoDB + MinIO + React dashboard): parallel workers, automatic BRDC ephemeris download, per-session analysis settings, WebSocket progress, and result persistence. See the live demo above. For local scripting, CN0Analyzer is stateless — instantiate one per thread and process files with a ThreadPoolExecutor.


License

PolyForm Noncommercial 1.0.0 with an attribution term — see LICENSE.

Free for research, education, personal and other non-commercial use, provided you credit the author and cite the library (see Citation below). Commercial use requires a separate license — contact miluta.flueras@cartografie.ro.

Citation

@software{geoveil_cn0_2026,
  title   = {geoveil-cn0: High-performance GNSS signal quality analysis},
  author  = {Dulea-Flueras, Miluta},
  year    = {2026},
  version = {0.4.1},
  url     = {https://github.com/miluta7/geoveil-cn0},
}

Made with Rust + Python · PyPI · Issues · ROMPOS

Metadata

Release files for geoveil-cn0 0.4.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for geoveil-cn0 0.4.1
File Size Uploaded
geoveil_cn0-0.4.1.tar.gz 678.9 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for geoveil-cn0 0.4.1
File
geoveil_cn0-0.4.1-cp312-cp312-win_amd64.whl CPython 3.12 CPython 3.12 Windows x86-64 Details
geoveil_cn0-0.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.12 CPython 3.12 Linux glibc 2.17+ x86-64 Details
geoveil_cn0-0.4.1-cp312-cp312-macosx_11_0_arm64.whl CPython 3.12 CPython 3.12 macOS 11.0+ ARM64 Details
geoveil_cn0-0.4.1-cp311-cp311-win_amd64.whl CPython 3.11 CPython 3.11 Windows x86-64 Details
geoveil_cn0-0.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.11 CPython 3.11 Linux glibc 2.17+ x86-64 Details
geoveil_cn0-0.4.1-cp311-cp311-macosx_11_0_arm64.whl CPython 3.11 CPython 3.11 macOS 11.0+ ARM64 Details
geoveil_cn0-0.4.1-cp310-cp310-win_amd64.whl CPython 3.10 CPython 3.10 Windows x86-64 Details
geoveil_cn0-0.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.10 CPython 3.10 Linux glibc 2.17+ x86-64 Details
geoveil_cn0-0.4.1-cp310-cp310-macosx_11_0_arm64.whl CPython 3.10 CPython 3.10 macOS 11.0+ ARM64 Details
geoveil_cn0-0.4.1-cp39-cp39-win_amd64.whl CPython 3.9 CPython 3.9 Windows x86-64 Details
geoveil_cn0-0.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.9 CPython 3.9 Linux glibc 2.17+ x86-64 Details
geoveil_cn0-0.4.1-cp39-cp39-macosx_11_0_arm64.whl CPython 3.9 CPython 3.9 macOS 11.0+ ARM64 Details

Total release size: 6.3 MB

Release files / geoveil_cn0-0.4.1.tar.gz

Download URL geoveil_cn0-0.4.1.tar.gz
Size 678.9 kB
Tags Source
SHA-256 checksum
How to use checksums
3a69766410ce914b71ea0e0fb7555cb8215844dd1c491c7471dd0e63212bd7e6
BLAKE2b-256 checksum
How to use checksums
e46489cf73f5fa61b3f861a7d7029b84908378a48009b4ff565674f31510e5cd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release files / geoveil_cn0-0.4.1-cp312-cp312-win_amd64.whl

Download URL geoveil_cn0-0.4.1-cp312-cp312-win_amd64.whl
Size 447.2 kB
Tags CPython 3.12 Windows x86-64
SHA-256 checksum
How to use checksums
1ed316c7ff6e6645339997176a7906f1ef0ec68a247a9de497ec9fb0085948a5
BLAKE2b-256 checksum
How to use checksums
085dadc6cbe909160b58d790dac5b73780592fbcf0bb191937420a740b8a2e75
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release files / geoveil_cn0-0.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL geoveil_cn0-0.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 496.3 kB
Tags CPython 3.12 Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
7b55757961c5eb654e21ff3707a485ebd1d4492a93494d7b91c755988813d421
BLAKE2b-256 checksum
How to use checksums
d65661f319a8c43feb330820dfab35f9f048be061a711d14a98cc8b4ea8368a5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release files / geoveil_cn0-0.4.1-cp312-cp312-macosx_11_0_arm64.whl

Download URL geoveil_cn0-0.4.1-cp312-cp312-macosx_11_0_arm64.whl
Size 452.1 kB
Tags CPython 3.12 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
409e02c93de52091f20017ed91b0f38514b5ff01977ae474c850549cd40df5a2
BLAKE2b-256 checksum
How to use checksums
92ee4f48b35fe7dbc7b20a7520e4bac5edd088f59ba1ceda1012e934e1c186a6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release files / geoveil_cn0-0.4.1-cp311-cp311-win_amd64.whl

Download URL geoveil_cn0-0.4.1-cp311-cp311-win_amd64.whl
Size 445.8 kB
Tags CPython 3.11 Windows x86-64
SHA-256 checksum
How to use checksums
b33b7ca609db9b7ca39722b4117660beb81f4ce69953137fbe6c025d52045248
BLAKE2b-256 checksum
How to use checksums
112e78e75e690aa74190f3ea2e18e6943f03a1c6612a6949cc9d0a102620be40
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release files / geoveil_cn0-0.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL geoveil_cn0-0.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 495.6 kB
Tags CPython 3.11 Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
948ccf3284e27a1de4999c4cd5799daa4c31fb5ebe8da93792f7e9f189464591
BLAKE2b-256 checksum
How to use checksums
99b59a64bcaafa0fae3b92a56eff6c44bd7a940cbea1c68a33365a58a37d8fad
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release files / geoveil_cn0-0.4.1-cp311-cp311-macosx_11_0_arm64.whl

Download URL geoveil_cn0-0.4.1-cp311-cp311-macosx_11_0_arm64.whl
Size 452.3 kB
Tags CPython 3.11 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
57d5a79bfc05d307a91ed482f506efe837a5109a485ffec954b2b4c3af283fe5
BLAKE2b-256 checksum
How to use checksums
df44974a54b67c10aa2ab567e8e16ebed2379ce2bb52185940ac2c370eaa302c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release files / geoveil_cn0-0.4.1-cp310-cp310-win_amd64.whl

Download URL geoveil_cn0-0.4.1-cp310-cp310-win_amd64.whl
Size 446.0 kB
Tags CPython 3.10 Windows x86-64
SHA-256 checksum
How to use checksums
6a5b2c67218acfd5df46d490b373c5e4ce93325f4f93ef2eb9f6a32505f480d8
BLAKE2b-256 checksum
How to use checksums
f76aceac297048926f3d9124aaae54df822245d5c820fe4b37f0c8de10d3ac83
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release files / geoveil_cn0-0.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL geoveil_cn0-0.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 495.4 kB
Tags CPython 3.10 Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
0c1626bfbb6f9a6080be86183115b761951828bd9dabf4fea93d7170e6e71b11
BLAKE2b-256 checksum
How to use checksums
1a1b42c9e198876f87020e8a2cb182ca7e24de41ac87bf06d32a5bf5fad7d386
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release files / geoveil_cn0-0.4.1-cp310-cp310-macosx_11_0_arm64.whl

Download URL geoveil_cn0-0.4.1-cp310-cp310-macosx_11_0_arm64.whl
Size 452.2 kB
Tags CPython 3.10 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
7bd07774b89ab09b3766d84a76715984cb55f05ecb7c653476c012b97aaf2d96
BLAKE2b-256 checksum
How to use checksums
1892c605d84a78c180c40a02e1818b443165673976de09db35421914212d69b4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release files / geoveil_cn0-0.4.1-cp39-cp39-win_amd64.whl

Download URL geoveil_cn0-0.4.1-cp39-cp39-win_amd64.whl
Size 446.7 kB
Tags CPython 3.9 Windows x86-64
SHA-256 checksum
How to use checksums
75e1e6056d1602b4ce35bbdd28af496a409042017ba890c48f4f4769739c3e12
BLAKE2b-256 checksum
How to use checksums
7422cb38e9c7235e5f63436a0ffcc78c1f3e7370dbc694a1d38fb32e27ac79ab
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release files / geoveil_cn0-0.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL geoveil_cn0-0.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 495.9 kB
Tags CPython 3.9 Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
2bbf3619a8826d53dc09f568286bcdc4a08ba6963eba4a829c6f81e70aa59375
BLAKE2b-256 checksum
How to use checksums
068d8d973b1c7d9d1414c63dde05803231253ee107d8c8f418cad9f4275352eb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release files / geoveil_cn0-0.4.1-cp39-cp39-macosx_11_0_arm64.whl

Download URL geoveil_cn0-0.4.1-cp39-cp39-macosx_11_0_arm64.whl
Size 452.6 kB
Tags CPython 3.9 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
e04cbfa79d94d7c853fa1dfdb19db9912294179349f9771536e467c1302ae8b0
BLAKE2b-256 checksum
How to use checksums
8fdf78d34629aef7128dd020a78c3dffc80aeab31d0fe9b9a88f505701280d70
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release history Release notifications | RSS feed

0.4.2

13 release files

This release

0.4.1 This release

13 release files

0.4.0

13 release files

0.3.8

13 release files

0.3.7

6 release files

0.3.6

16 release files

0.3.5

16 release files

0.3.4

16 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

3 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page