mirror of
https://git.ianrenton.com/ian/spothole.git
synced 2026-04-29 18:25:58 +00:00
Radio blackout (R) scale
This commit is contained in:
@@ -5,7 +5,7 @@ from dataclasses import dataclass
|
||||
# Each threshold-based table is a list of (min_value, description) pairs in descending order;
|
||||
# the first entry whose threshold the value meets or exceeds is used.
|
||||
|
||||
BLACKOUT_DESCRIPTIONS = {
|
||||
XRAY_CLASS_DESCRIPTIONS = {
|
||||
"X": "Wide area HF radio blackout across sunlit side",
|
||||
"M": "Occasional loss of HF communications on sunlit side",
|
||||
"C": "Low absorption of HF signals on sunlit side",
|
||||
@@ -71,6 +71,28 @@ ELECTRON_FLUX_DESCRIPTIONS = [
|
||||
]
|
||||
|
||||
|
||||
def _xray_blackout_scale(xray):
|
||||
"""Return the NOAA Radio Blackout scale number (R0-R5) for the given X-ray flux class string
|
||||
(e.g. "M4.5", "X12")."""
|
||||
|
||||
if not xray or len(xray) < 2:
|
||||
return 0
|
||||
letter = xray[0].upper()
|
||||
try:
|
||||
number = float(xray[1:])
|
||||
except ValueError:
|
||||
return 0
|
||||
if letter == 'M':
|
||||
return 1 if number < 5 else 2
|
||||
if letter == 'X':
|
||||
if number < 10:
|
||||
return 3
|
||||
if number < 20:
|
||||
return 4
|
||||
return 5
|
||||
return 0
|
||||
|
||||
|
||||
def _lookup_by_threshold(value, table, default=None):
|
||||
"""Return the description from a threshold table for the given numeric value.
|
||||
The table is a list of (min_value, description) pairs in descending order."""
|
||||
@@ -108,7 +130,7 @@ class SolarConditions:
|
||||
# K-index (3-hour geomagnetic activity)
|
||||
k_index: int = None
|
||||
# X-ray flux class, e.g. "B2.3", "C1.0"
|
||||
x_ray: str = None
|
||||
xray: str = None
|
||||
# Proton flux
|
||||
proton_flux: int = None
|
||||
# Electron flux
|
||||
@@ -141,8 +163,10 @@ class SolarConditions:
|
||||
blackout_forecast_r3_or_greater: dict = None
|
||||
|
||||
# Derived values (populated by infer_descriptions())
|
||||
# HF radio blackout risk description, derived from x_ray
|
||||
blackout_desc: str = None
|
||||
# HF radio blackout risk description, derived from xray
|
||||
xray_desc: str = None
|
||||
# HF radio blackout scale number (R0-R5), derived from xray
|
||||
radio_blackout_scale: int = None
|
||||
# Solar radiation storm level description, derived from proton_flux
|
||||
proton_flux_desc: str = None
|
||||
# Solar radiation storm scale number (S0-S5), derived from proton_flux
|
||||
@@ -159,10 +183,9 @@ class SolarConditions:
|
||||
def infer_descriptions(self):
|
||||
"""Populate derived text description fields from the current numeric/raw field values."""
|
||||
|
||||
# blackout_desc: use the X-ray flux class letter (first character of x_ray)
|
||||
if self.x_ray and len(self.x_ray) > 0:
|
||||
self.blackout_desc = BLACKOUT_DESCRIPTIONS.get(self.x_ray[0].upper())
|
||||
|
||||
if self.xray and len(self.xray) > 0:
|
||||
self.xray_desc = XRAY_CLASS_DESCRIPTIONS.get(self.xray[0].upper())
|
||||
self.radio_blackout_scale = _xray_blackout_scale(self.xray)
|
||||
self.proton_flux_desc = _lookup_by_threshold(self.proton_flux, PROTON_FLUX_DESCRIPTIONS)
|
||||
self.solar_storm_scale = _lookup_by_threshold(self.proton_flux, SOLAR_STORM_SCALES)
|
||||
self.geomag_storm_desc = _lookup_by_threshold(self.k_index, GEOMAG_STORM_DESCRIPTIONS)
|
||||
|
||||
Reference in New Issue
Block a user