Atmospheric Propagation (ITU-R)
ITU-R P-series atmospheric propagation models for computing attenuation on Earth-to-space radio paths. Based on the ITU-Rpy library.
Quick Start
Compute the total atmospheric attenuation for a ground station in Madrid receiving at 14.25 GHz from a satellite at 30° elevation:
import lox_space as lox
losses = lox.EnvironmentalLosses(
lat=40.4 * lox.deg,
lon=-3.7 * lox.deg,
frequency=14.25 * lox.GHz,
elevation=30.0 * lox.deg,
probability=0.01, # exceeded 0.01% of the year
diameter=1.2 * lox.m, # antenna diameter
)
print(f"Rain: {losses.rain}")
print(f"Gaseous: {losses.gaseous}")
print(f"Cloud: {losses.cloud}")
print(f"Scintillation: {losses.scintillation}")
print(f"Total: {losses.atmospheric}")
The same computation is also available as a free-standing function:
losses = lox.atmospheric_attenuation_slant_path(
lat=40.4 * lox.deg, lon=-3.7 * lox.deg,
frequency=14.25 * lox.GHz, elevation=30.0 * lox.deg,
probability=0.01, diameter=1.2 * lox.m,
)
For link budgets with known loss values, use EnvironmentalLosses.from_values
or EnvironmentalLosses.none:
losses = lox.EnvironmentalLosses.from_values(rain=2.0 * lox.dB, gaseous=0.5 * lox.dB)
losses = lox.EnvironmentalLosses.none()
The result plugs directly into LinkStats.calculate for link budget analysis.
Individual Models
Each ITU-R recommendation is also available as a standalone function.
Rain Attenuation (P.618)
a_rain = lox.rain_attenuation(
lat=40.4 * lox.deg,
lon=-3.7 * lox.deg,
frequency=14.25 * lox.GHz,
elevation=30.0 * lox.deg,
probability=0.01,
)
Gaseous Attenuation (P.676)
a_oxygen, a_water = lox.gaseous_attenuation_slant_path(
frequency=14.25 * lox.GHz,
elevation=30.0 * lox.deg,
pressure=1013.25 * lox.hPa,
rho=7.5, # water vapour density (g/m³)
temperature=288.15 * lox.K,
)
Cloud Attenuation (P.840)
a_cloud = lox.cloud_attenuation(
lat=40.4 * lox.deg,
lon=-3.7 * lox.deg,
elevation=30.0 * lox.deg,
frequency=14.25 * lox.GHz,
probability=1.0,
)
Scintillation (P.618)
a_scint = lox.scintillation_attenuation(
frequency=14.25 * lox.GHz,
elevation=30.0 * lox.deg,
probability=0.01,
diameter=1.2 * lox.m,
lat=40.4 * lox.deg,
lon=-3.7 * lox.deg,
)
Specific Rain Attenuation (P.838)
gamma_r = lox.rain_specific_attenuation(
rain_rate=25.0, # mm/h
frequency=14.25 * lox.GHz,
elevation=30.0 * lox.deg,
)
Geophysical Data Lookups
Topographic Altitude (P.1511)
alt = lox.topographic_altitude(lat=27.99 * lox.deg, lon=86.93 * lox.deg)
print(f"Altitude: {alt.to_kilometers():.1f} km")
Surface Temperature (P.1510)
t = lox.surface_mean_temperature(lat=0.0 * lox.deg, lon=0.0 * lox.deg)
print(f"Temperature: {t.to_kelvin():.1f} K")
Rainfall Rate (P.837)
r = lox.rainfall_rate(lat=40.4 * lox.deg, lon=-3.7 * lox.deg, probability=0.01)
print(f"Rainfall rate: {r:.1f} mm/h")
Rain Height (P.839)
h = lox.rain_height(lat=40.4 * lox.deg, lon=-3.7 * lox.deg)
print(f"Rain height: {h.to_kilometers():.1f} km")
Link Budget Integration
EnvironmentalLosses can be passed directly to LinkStats.calculate:
losses = lox.EnvironmentalLosses(
lat=40.4 * lox.deg,
lon=-3.7 * lox.deg,
frequency=29.0 * lox.GHz,
elevation=30.0 * lox.deg,
probability=0.01,
diameter=0.6 * lox.m,
)
stats = lox.LinkStats.calculate(
tx_system=tx,
rx_system=rx,
channel=channel,
range=1000.0 * lox.km,
tx_angle=0.0 * lox.rad,
rx_angle=0.0 * lox.rad,
losses=losses,
)
Data Files
Grid-based models (P.1511, P.1510, P.836, P.837, P.839, P.840, P.453) require reference data from the ITU. This data is automatically downloaded from PyPI and converted during the build process. No manual setup is needed.
Implemented Recommendations
| Recommendation | Description |
|---|---|
| P.453-13 | Radio refractive index |
| P.618-14 | Earth-space propagation (rain, scintillation, XPD) |
| P.676-13 | Gaseous attenuation (O₂ + H₂O) |
| P.835-6 | Reference standard atmospheres |
| P.836-6 | Water vapour surface density |
| P.837-7 | Rainfall rate |
| P.838-3 | Specific rain attenuation |
| P.839-4 | Rain height |
| P.840-9 | Cloud and fog attenuation |
| P.1510-1 | Surface temperature |
| P.1511-2 | Topographic altitude |
atmospheric_attenuation_slant_path
builtin
atmospheric_attenuation_slant_path(
lat: Angle,
lon: Angle,
frequency: Frequency,
elevation: Angle,
probability: float,
diameter: Distance,
polarisation_tilt: Angle | None = None,
) -> EnvironmentalLosses
Computes atmospheric attenuation on a slant path, returning individual
contributions as an EnvironmentalLosses object.
Parameters:
-
(latAngle) –Latitude.
-
(lonAngle) –Longitude.
-
(frequencyFrequency) –Frequency.
-
(elevationAngle) –Elevation angle.
-
(probabilityfloat) –Exceedance probability (% of average year).
-
(diameterDistance) –Physical antenna diameter.
-
(polarisation_tiltAngle | None, default:None) –Polarisation tilt angle (default 45° for circular).
Returns:
-
EnvironmentalLosses–EnvironmentalLosses with rain, gaseous, cloud, scintillation, and
-
EnvironmentalLosses–depolarization fields populated.
rain_attenuation
builtin
rain_attenuation(
lat: Angle,
lon: Angle,
frequency: Frequency,
elevation: Angle,
probability: float,
polarisation_tilt: Angle | None = None,
) -> Decibel
Computes rain attenuation exceeded for a given probability (P.618-13).
Parameters:
-
(latAngle) –Latitude.
-
(lonAngle) –Longitude.
-
(frequencyFrequency) –Frequency.
-
(elevationAngle) –Elevation angle.
-
(probabilityfloat) –Exceedance probability (% of average year).
-
(polarisation_tiltAngle | None, default:None) –Polarisation tilt angle (default 45° for circular).
Returns:
-
Decibel–Rain attenuation.
gaseous_attenuation_slant_path
builtin
gaseous_attenuation_slant_path(
frequency: Frequency,
elevation: Angle,
pressure: Pressure,
rho: float,
temperature: Temperature,
) -> tuple[Decibel, Decibel]
Computes gaseous attenuation on a slant path (P.676-12 approximate method).
Parameters:
-
(frequencyFrequency) –Frequency.
-
(elevationAngle) –Elevation angle.
-
(pressurePressure) –Surface pressure.
-
(rhofloat) –Surface water vapour density in g/m³.
-
(temperatureTemperature) –Surface temperature.
Returns:
cloud_attenuation
builtin
scintillation_attenuation
builtin
scintillation_attenuation(
frequency: Frequency,
elevation: Angle,
probability: float,
diameter: Distance,
eta: float = 0.5,
lat: Angle | None = None,
lon: Angle | None = None,
) -> Decibel
Computes tropospheric scintillation fade depth exceeded for a given probability (P.618-13).
Parameters:
-
(frequencyFrequency) –Frequency.
-
(elevationAngle) –Elevation angle.
-
(probabilityfloat) –Exceedance probability (% of average year).
-
(diameterDistance) –Physical antenna diameter.
-
(etafloat, default:0.5) –Antenna efficiency (default 0.5).
-
(latAngle | None, default:None) –Latitude (for N_wet lookup).
-
(lonAngle | None, default:None) –Longitude (for N_wet lookup).
Returns:
-
Decibel–Scintillation attenuation.
rain_specific_attenuation
builtin
rain_specific_attenuation(
rain_rate: float,
frequency: Frequency,
elevation: Angle,
polarisation_tilt: Angle | None = None,
) -> float
Computes the specific attenuation from rain (P.838-3).
Parameters:
-
(rain_ratefloat) –Rainfall rate in mm/h.
-
(frequencyFrequency) –Frequency.
-
(elevationAngle) –Elevation angle.
-
(polarisation_tiltAngle | None, default:None) –Polarisation tilt angle (default 45° for circular).
Returns:
-
float–Specific rain attenuation in dB/km.
topographic_altitude
builtin
surface_mean_temperature
builtin
surface_mean_temperature(lat: Angle, lon: Angle) -> Temperature
Returns the annual mean surface temperature at the given location (P.1510-1).
Parameters:
Returns:
-
Temperature–Temperature.