GNSS CN0 Analysis Library - Interference, Jamming & Spoofing Detection
Project description
geoveil-cn0
High-performance GNSS CN0 (Carrier-to-Noise) Signal Quality Analysis Library
A Rust-powered Python library for analyzing GNSS signal quality from RINEX observation files. Detect interference, jamming, spoofing, and multipath effects with research-grade algorithms.
Features
- 🛰️ Multi-GNSS Support: GPS, GLONASS, Galileo, BeiDou, QZSS, NavIC
- 📊 CN0 Analysis: Signal strength statistics, timeseries, and quality scoring
- 🚨 Threat Detection: Jamming, spoofing, and interference indicators
- 📈 Anomaly Detection: Configurable sensitivity for signal anomalies
- 🗺️ Skyplot Data: Satellite positions with azimuth/elevation (requires NAV file)
- ⚡ High Performance: Rust core with Python bindings via PyO3
- 📁 RINEX Support: Parse RINEX 2.x, 3.x, and 4.x observation files
- 🧭 Navigation Files: BRDC broadcast ephemeris and SP3 precise orbits
Installation
pip install geoveil-cn0
Quick Start
import geoveil_cn0 as gcn0
# Create analysis configuration
config = gcn0.AnalysisConfig(
min_elevation=5.0, # Elevation mask (degrees)
time_bin_seconds=60, # Time binning for statistics
detect_anomalies=True, # Enable anomaly detection
anomaly_sensitivity=0.3, # Sensitivity (0-1, lower = fewer false positives)
interference_threshold_db=8.0, # CN0 drop threshold for interference
)
# Create analyzer
analyzer = gcn0.CN0Analyzer(config)
# Analyze observation file (with optional navigation for skyplots)
result = analyzer.analyze_with_nav("observation.rnx", "navigation.rnx")
# Access results
print(f"Quality Score: {result.quality_score.overall}/100 ({result.quality_score.rating})")
print(f"Average CN0: {result.avg_cn0:.1f} dB-Hz")
print(f"Jamming Detected: {result.jamming_detected}")
print(f"Spoofing Detected: {result.spoofing_detected}")
print(f"Anomalies: {result.anomaly_count}")
# Get detailed data
for constellation in result.constellations:
stats = result.get_constellation_summary(constellation)
print(f"{constellation}: {stats['satellites_observed']} sats, CN0={stats['cn0_mean']:.1f} dB-Hz")
# Export to JSON
json_data = result.to_json()
Quality Score Components
The quality score (0-100) is computed from multiple factors:
| Component | Weight | Description |
|---|---|---|
| CN0 Quality | 35% | Signal strength relative to thresholds |
| Availability | 20% | Satellite availability vs expected |
| Continuity | 20% | Data continuity (gaps, cycle slips) |
| Stability | 15% | CN0 variance over time |
| Diversity | 10% | Multi-constellation coverage |
Threat Detection Thresholds
Based on research from ITU-R M.1902-1, Stanford GPS Lab, and GPS Solutions journal:
- Jamming: Rapid CN0 drops >6 dB in <3 seconds
- Spoofing: Abnormally uniform CN0 (std <2 dB) or elevated average
- Interference: CN0 degradation >4 dB from baseline (ITU I/N=-6dB criterion)
API Reference
AnalysisConfig
config = gcn0.AnalysisConfig(
min_elevation=5.0, # Elevation cutoff in degrees
time_bin_seconds=60, # Time bin for statistics
systems=['G', 'R', 'E', 'C'], # GNSS systems to analyze
detect_anomalies=True, # Enable anomaly detection
anomaly_sensitivity=0.3, # 0-1, lower = stricter
interference_threshold_db=8.0, # dB drop for interference flag
verbose=False, # Print debug info
)
CN0Analyzer
analyzer = gcn0.CN0Analyzer(config)
# Analyze without navigation (no skyplots)
result = analyzer.analyze_file("observation.rnx")
# Analyze with navigation (enables skyplots and elevation filtering)
result = analyzer.analyze_with_nav("observation.rnx", "navigation.rnx")
AnalysisResult
| Property | Type | Description |
|---|---|---|
quality_score |
QualityScore | Overall quality metrics |
avg_cn0 |
float | Mean CN0 in dB-Hz |
cn0_std_dev |
float | CN0 standard deviation |
min_cn0, max_cn0 |
float | CN0 range |
jamming_detected |
bool | Jamming indicator |
spoofing_detected |
bool | Spoofing indicator |
interference_detected |
bool | Interference indicator |
anomaly_count |
int | Number of anomalies |
constellations |
list | Available constellations |
duration_hours |
float | Observation duration |
epoch_count |
int | Number of epochs |
Methods
# Get constellation-specific statistics
stats = result.get_constellation_summary("GPS") # Returns dict
# Get anomaly list
anomalies = result.get_anomalies() # Returns list of dicts
# Get timeseries data for plotting
ts_data = result.get_timeseries_data() # Returns dict with timestamps, cn0_mean, etc.
# Get skyplot data (requires navigation file)
skyplot = result.get_skyplot_data() # Returns list of satellite traces
# Export to JSON
json_str = result.to_json()
Jupyter Notebook Widget
A ready-to-use interactive widget is included:
# In Jupyter notebook
exec(open("geoveil_cn0_gui.py").read())
Features:
- File upload or path input
- Auto-download BRDC navigation files
- Interactive Plotly charts
- Quality radar, skyplots, heatmaps, timeseries
- HTML report export
Data Sources
The library supports navigation data from:
- BRDC: IGS combined broadcast ephemeris
- SP3: Precise orbits from ESA, GFZ, CODE, WHU
- TLE: CelesTrak GNSS TLE (fallback)
Requirements
- Python 3.8+
- No runtime dependencies (Rust binary)
Optional for notebooks:
plotly- Interactive chartspandas- Data manipulationipywidgets- Jupyter widgets
License
MIT License - see LICENSE for details.
Author
Miluta Dulea-Flueras
Contributing
Contributions welcome! Please open an issue or pull request on GitHub.
Citation
If you use this library in research, please cite:
@software{geoveil_cn0,
author = {Dulea-Flueras, Miluta},
title = {geoveil-cn0: GNSS CN0 Signal Quality Analysis Library},
year = {2026},
url = {https://github.com/miluta7/geoveil-cn0}
}
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
Built Distribution
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.3.tar.gz.
File metadata
- Download URL: geoveil_cn0-0.3.3.tar.gz
- Upload date:
- Size: 123.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c6f90ae6b82c99135599c68a4733ea2fb7b6f485b52b14f01210f54fc6ae2d35
|
|
| MD5 |
dde0d3d71b258974fc27f4925089005d
|
|
| BLAKE2b-256 |
a82e55be049eef802ad02e787dad4f787b95b72130d63f8a72ccb499e9c71feb
|
Provenance
The following attestation bundles were made for geoveil_cn0-0.3.3.tar.gz:
Publisher:
ci.yml on miluta7/geoveil-cn0
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
geoveil_cn0-0.3.3.tar.gz -
Subject digest:
c6f90ae6b82c99135599c68a4733ea2fb7b6f485b52b14f01210f54fc6ae2d35 - Sigstore transparency entry: 835721880
- Sigstore integration time:
-
Permalink:
miluta7/geoveil-cn0@1313d9d56b0f6241d3db572efe41e575b2c2f01a -
Branch / Tag:
refs/tags/v0.3.3 - Owner: https://github.com/miluta7
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@1313d9d56b0f6241d3db572efe41e575b2c2f01a -
Trigger Event:
push
-
Statement type:
File details
Details for the file geoveil_cn0-0.3.3-cp310-cp310-manylinux_2_39_x86_64.whl.
File metadata
- Download URL: geoveil_cn0-0.3.3-cp310-cp310-manylinux_2_39_x86_64.whl
- Upload date:
- Size: 502.8 kB
- Tags: CPython 3.10, manylinux: glibc 2.39+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2c905a1d761199b79eea6021a114474115cf16f23ecccc7ed50023c50b0cc31d
|
|
| MD5 |
560403fe2769a90aba7dc17eeba3ff48
|
|
| BLAKE2b-256 |
a07a7bf6ea2e2583ebc7c256cdee1f31021fa2843d75b952025c95d7aa9d01e2
|
Provenance
The following attestation bundles were made for geoveil_cn0-0.3.3-cp310-cp310-manylinux_2_39_x86_64.whl:
Publisher:
ci.yml on miluta7/geoveil-cn0
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
geoveil_cn0-0.3.3-cp310-cp310-manylinux_2_39_x86_64.whl -
Subject digest:
2c905a1d761199b79eea6021a114474115cf16f23ecccc7ed50023c50b0cc31d - Sigstore transparency entry: 835721882
- Sigstore integration time:
-
Permalink:
miluta7/geoveil-cn0@1313d9d56b0f6241d3db572efe41e575b2c2f01a -
Branch / Tag:
refs/tags/v0.3.3 - Owner: https://github.com/miluta7
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@1313d9d56b0f6241d3db572efe41e575b2c2f01a -
Trigger Event:
push
-
Statement type: