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.3 s per 24h file Zero Python dependencies ThreadPool-parallel batches |
📡 RINEX Support v2.x / v3.x / v4.x Hatanaka compression SP3 precise orbits |
🔬 Full API JSON export · Timeseries Skyplot data · Anomaly list Desktop GUI script included |
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 CN0Analyzer, AnalyzerConfig
config = AnalyzerConfig(
time_bin_seconds=300, # 5-minute bins
anomaly_sensitivity=0.5, # 0.0 = permissive, 1.0 = strict
interference_threshold_db=6.0,
)
analyzer = CN0Analyzer(config)
result = analyzer.analyze("COST00ROU_R_20260408_0100_30S_MO.rnx")
print(f"Quality score : {result.quality_score:.1f} / 100 ({result.quality_grade})")
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} tracked")
print(f"Constellations: {', '.join(result.active_constellations)}")
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:.0%}")
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/.crx/.gz"] --> 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
| File size | Epochs | Satellites | Time |
|---|---|---|---|
| 2.1 MB | 2 880 | 18–24 | 0.18 s |
| 8.4 MB | 11 520 | 22–28 | 0.26 s |
| 31 MB | 43 200 | 24–32 | 0.29 s |
| 100 MB | 86 400 | 28–36 | 0.31 s |
Benchmarked on a single core (Intel i7-1185G7). ThreadPool batch processing scales linearly with core count.
Quality Score Components
The composite quality score (0–100) is computed from five weighted components:
| Component | Weight | Description |
|---|---|---|
| CN0 Quality | 35% | Mean signal strength relative to expected |
| Availability | 25% | Fraction of epochs with sufficient satellites |
| Continuity | 20% | Absence of tracking gaps and cycle slips |
| Stability | 12% | Low variance in per-satellite CN0 |
| Diversity | 8% | Multi-constellation coverage |
Letter grades: A ≥ 90 · B ≥ 80 · C ≥ 70 · D ≥ 60 · F < 60
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
AnalyzerConfig
| Parameter | Type | Default | Description |
|---|---|---|---|
time_bin_seconds |
int |
300 |
Seconds per analysis bin |
min_elevation_deg |
float |
10.0 |
Mask angle in degrees |
anomaly_sensitivity |
float |
0.5 |
Detection sensitivity 0–1 |
interference_threshold_db |
float |
6.0 |
Interference trigger (dB) |
spoofing_unexpected_threshold |
float |
0.4 |
Fraction of unexpected sats |
spoofing_min_unexpected_count |
int |
8 |
Minimum count to flag |
enable_timeseries |
bool |
True |
Output per-bin CN0 data |
enable_skyplot |
bool |
False |
Compute Az/El tracks |
AnalysisResult — key properties
| Property | Type | Description |
|---|---|---|
quality_score |
float |
Composite 0–100 |
quality_grade |
str |
Letter A–F |
jamming_detected |
bool |
Jamming flag |
spoofing_detected |
bool |
Spoofing flag |
interference_detected |
bool |
Interference flag |
has_visibility_prediction |
bool |
Nav file was provided |
visibility_confirmation_rate |
float |
Fraction of predicted sats seen |
visibility_mean_unexpected |
float |
Mean unexpected sats per epoch |
visibility_mean_missing |
float |
Mean missing sats per epoch |
constellation_stats |
dict |
Per-GNSS stats |
timeseries |
list |
Per-bin CN0 data |
anomalies |
list |
Detected anomaly events |
Supported Formats
| Format | Extensions | Notes |
|---|---|---|
| RINEX 2.x | .obs, .??o |
All standard types |
| RINEX 3.x | .rnx, .obs |
Mixed observation files |
| RINEX 4.x | .rnx |
Latest format |
| Hatanaka | .crx, .??d |
Compressed observation |
| Gzip | .gz |
Any RINEX inside |
| ZIP | .zip |
Single-file archives |
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.
Citation
@software{geoveil_cn0_2026,
title = {geoveil-cn0: High-performance GNSS signal quality analysis},
author = {Dulea-Flueras, Miluta},
year = {2026},
version = {0.3.8},
url = {https://github.com/miluta7/geoveil-cn0},
}
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file geoveil_cn0-0.3.9.tar.gz.
File metadata
- Download URL: geoveil_cn0-0.3.9.tar.gz
- Upload date:
- Size: 151.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d3e09499a6fe3f723a173ca41e929c69dc325bd4ad1e35618584032257d37b7a
|
|
| MD5 |
d57e17eb26733e864cff4462ffaf9aa8
|
|
| BLAKE2b-256 |
852662e434385695f4186b8b5bc687ae9ecf22e83755e0d5150d2e4ae1e7c6a8
|
File details
Details for the file geoveil_cn0-0.3.9-cp312-cp312-win_amd64.whl.
File metadata
- Download URL: geoveil_cn0-0.3.9-cp312-cp312-win_amd64.whl
- Upload date:
- Size: 437.7 kB
- Tags: CPython 3.12, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
785115d3b574a80b4acbf9a3592f8c49976d4298b13cf940117cd6e880133f67
|
|
| MD5 |
fb7181dde8ff06a8c2476680508856dc
|
|
| BLAKE2b-256 |
e204af92e4f572ef1489f477fd6c97c0cf7dae4122c8783a111d060cb40a4ec9
|
File details
Details for the file geoveil_cn0-0.3.9-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: geoveil_cn0-0.3.9-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 491.3 kB
- Tags: CPython 3.12, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a68f52e54720cecf4fbce1967f8005571a541cb5763ad3d124c86b1866bdf5f4
|
|
| MD5 |
0a91ff052d902f9d6276850fa8f5e45f
|
|
| BLAKE2b-256 |
2411f5f0f6a5f181363937b5cba426b3afde28b94c3241c56c05238189c9da64
|
File details
Details for the file geoveil_cn0-0.3.9-cp312-cp312-macosx_11_0_arm64.whl.
File metadata
- Download URL: geoveil_cn0-0.3.9-cp312-cp312-macosx_11_0_arm64.whl
- Upload date:
- Size: 446.0 kB
- Tags: CPython 3.12, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6fcdb01945ea09211296e7debf8496f540b9a60587f54e674c6ad1a5e159e42b
|
|
| MD5 |
aad981eded2ac350c2c2fb0de6059f1b
|
|
| BLAKE2b-256 |
ea31b8e8f3b57431bbb7046bffa1efc07b5c56e472a1cdbce4295e7143125fd2
|
File details
Details for the file geoveil_cn0-0.3.9-cp311-cp311-win_amd64.whl.
File metadata
- Download URL: geoveil_cn0-0.3.9-cp311-cp311-win_amd64.whl
- Upload date:
- Size: 437.3 kB
- Tags: CPython 3.11, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5da0ae3cbcb118e0aee7a288dcee4bf656efbda850e38e62c8632d81e7c74701
|
|
| MD5 |
43d99d880482e1aed9d9f7ad5822ba9d
|
|
| BLAKE2b-256 |
ac1d116be78ef8b2d76f933f59a1a24b7fa10251284cb3a2183c746c38ec8bd0
|
File details
Details for the file geoveil_cn0-0.3.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: geoveil_cn0-0.3.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 489.8 kB
- Tags: CPython 3.11, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
be1e29d6dac7618c7940d4b7cfaab8c25b184110fc58fa00198a1720455900ce
|
|
| MD5 |
a03d16f91ab1ae9ae74d572f1a0fe58d
|
|
| BLAKE2b-256 |
03a663afdb7193255dafaa29d095367cd799074ff922e7842969fc9623315114
|
File details
Details for the file geoveil_cn0-0.3.9-cp311-cp311-macosx_11_0_arm64.whl.
File metadata
- Download URL: geoveil_cn0-0.3.9-cp311-cp311-macosx_11_0_arm64.whl
- Upload date:
- Size: 445.3 kB
- Tags: CPython 3.11, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dfa07d35b767de9f556240fb82c464f40e4add70592621422f1388712b3c44a2
|
|
| MD5 |
6e7afd472c381a093648961e8e0b996d
|
|
| BLAKE2b-256 |
ffe676573f8386ad2e644d3e121d53bde05fab21cbe0b5bab0c8436c0f8bf192
|
File details
Details for the file geoveil_cn0-0.3.9-cp310-cp310-win_amd64.whl.
File metadata
- Download URL: geoveil_cn0-0.3.9-cp310-cp310-win_amd64.whl
- Upload date:
- Size: 437.3 kB
- Tags: CPython 3.10, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c8fcdd74a7b4acd567280bcc98faa00ec9bee22f3093788570dc0d9e0e761778
|
|
| MD5 |
6b0b32d161e6ceb5899797c41536c56f
|
|
| BLAKE2b-256 |
bce7251b71a6d78498188a797ffbf4615679ab402a0dc16fa9047f01f704ee34
|
File details
Details for the file geoveil_cn0-0.3.9-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: geoveil_cn0-0.3.9-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 489.8 kB
- Tags: CPython 3.10, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
279d9924178a6f1439cc8b70f93e0603cc0b4654b4b4c4424dd20ca340eca648
|
|
| MD5 |
5940ec26611f47bda51c3ffa084a6ff4
|
|
| BLAKE2b-256 |
dedc64be1a51b50d06e274051c404f0f1a76abc928ab858859aecfac0b5df63f
|
File details
Details for the file geoveil_cn0-0.3.9-cp310-cp310-macosx_11_0_arm64.whl.
File metadata
- Download URL: geoveil_cn0-0.3.9-cp310-cp310-macosx_11_0_arm64.whl
- Upload date:
- Size: 445.5 kB
- Tags: CPython 3.10, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f841af74308c22f0a4174ce001f41c9ff771e35d5152ab36f582393afd9083c3
|
|
| MD5 |
9b245ffe61cc375ef0183cbc092f3763
|
|
| BLAKE2b-256 |
c37cfdcd92265e2e283fbc56ab5482f7e253223ce76e404ffae4ddf6a3d6c1f6
|
File details
Details for the file geoveil_cn0-0.3.9-cp39-cp39-win_amd64.whl.
File metadata
- Download URL: geoveil_cn0-0.3.9-cp39-cp39-win_amd64.whl
- Upload date:
- Size: 437.8 kB
- Tags: CPython 3.9, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d1c164b6f299ecb6e2473a86a5d6c94c593cbb4121078f6aa7c34a7e1423bf4b
|
|
| MD5 |
77926f30b62598d3d3a6657bc8523318
|
|
| BLAKE2b-256 |
8e2bc64411a0789d53eade8d3e090131ff57cfe3854d7bb6d32f39f94fd5ccdb
|
File details
Details for the file geoveil_cn0-0.3.9-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: geoveil_cn0-0.3.9-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 490.3 kB
- Tags: CPython 3.9, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
811bdf4384a124ffdc886cae78229d0f9df0084c098dc890e1c78e7bfb4e7aef
|
|
| MD5 |
6ea9a39f8923795d3ac36f76b67636da
|
|
| BLAKE2b-256 |
bf20b8bf62cd170165a0fb1df126660c08df941ab110347aa3d61feff123945a
|
File details
Details for the file geoveil_cn0-0.3.9-cp39-cp39-macosx_11_0_arm64.whl.
File metadata
- Download URL: geoveil_cn0-0.3.9-cp39-cp39-macosx_11_0_arm64.whl
- Upload date:
- Size: 445.5 kB
- Tags: CPython 3.9, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7ca624ef161ada9aa452fd0dc71f559265cfee94c53c7123410e9845c387f36e
|
|
| MD5 |
4c88fae9ad0ce9ea3c5f4c39c838cf5e
|
|
| BLAKE2b-256 |
2337a0d233e8e5eb37c1944f170c6936c5c5dd1b47152cb554bf4d4c66880e24
|