88 lines
3.5 KiB
Python
88 lines
3.5 KiB
Python
#!/usr/bin/env python3
|
||
"""Generate the Rust source for the ITU-R P.839-4 rain height table.
|
||
|
||
The recommendation gives the height of the zero degree isotherm as a
|
||
tabulated global grid at 1.5 degree resolution. This script reads the grid
|
||
from the ``itur`` reference package and emits a Rust module that embeds it as
|
||
integer tenths of a kilometre, which is the resolution the recommendation
|
||
publishes.
|
||
|
||
Usage:
|
||
|
||
python validation/tools/generate_p839_table.py > /tmp/p839_table.rs
|
||
|
||
生成 ITU-R P.839-4 雨顶高度表的 Rust 源码。
|
||
|
||
该建议书把零度等温线高度给出为 1.5 度分辨率的全球列表网格。本脚本从
|
||
``itur`` 参考包读取该网格,并输出一个 Rust 模块,把它以十分之一千米的整数
|
||
嵌入,这正是该建议书发布的分辨率。
|
||
|
||
用法:
|
||
|
||
python validation/tools/generate_p839_table.py > /tmp/p839_table.rs
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import sys
|
||
|
||
import numpy as np
|
||
|
||
BASE = (
|
||
"validation/.pixi/envs/default/lib/python3.12/site-packages/itur/data/839/"
|
||
)
|
||
|
||
# The grid resolution, in degrees.
|
||
# 网格分辨率,单位为度。
|
||
STEP_DEGREES = 1.5
|
||
|
||
|
||
def main() -> int:
|
||
heights = np.load(BASE + "v4_esa0height.npz")["arr_0"]
|
||
latitudes = np.load(BASE + "v4_esalat.npz")["arr_0"]
|
||
longitudes = np.load(BASE + "v4_esalon.npz")["arr_0"]
|
||
|
||
rows = heights.shape[0]
|
||
columns = heights.shape[1]
|
||
|
||
# The grid is regular: latitude runs from 90 down to -90 and longitude
|
||
# from 0 to 360, both in steps of 1.5 degrees.
|
||
# 该网格是规则的:纬度自 90 降到 -90,经度自 0 到 360,步长均为 1.5 度。
|
||
assert np.allclose(latitudes[:, 0], np.linspace(90.0, -90.0, rows)), "latitude grid"
|
||
assert np.allclose(longitudes[0, :], np.linspace(0.0, 360.0, columns)), "longitude grid"
|
||
|
||
# The recommendation publishes the height to the nearest metre, so the
|
||
# table is stored in metres to avoid losing precision.
|
||
# 该建议书把高度发布到最近一米,故该表以米存储以避免损失精度。
|
||
metres = np.round(heights * 1000.0).astype(np.uint16)
|
||
|
||
print("/// The height of the zero degree isotherm, in metres.")
|
||
print("///")
|
||
print("/// The grid runs from 90 degrees north to 90 degrees south in the row")
|
||
print("/// direction and from 0 to 360 degrees east in the column direction,")
|
||
print("/// both in steps of 1.5 degrees, so there are 121 rows and 241 columns.")
|
||
print("/// The value at a fractional latitude or longitude is found by bilinear")
|
||
print("/// interpolation between the four surrounding points.")
|
||
print("///")
|
||
print("/// Source: ITU-R Recommendation P.839-4, *Rain height model for prediction")
|
||
print("/// methods*, which tabulates the isotherm height on this grid.")
|
||
print("///")
|
||
print("/// 零度等温线的高度,单位为米。")
|
||
print("///")
|
||
print("/// 网格在行方向上自北纬 90 度到南纬 90 度,在列方向上自东经 0 度到")
|
||
print("/// 360 度,步长均为 1.5 度,故有 121 行 241 列。分数纬度或经度处的值")
|
||
print("/// 由周围四点之间的双线性插值求得。")
|
||
print("///")
|
||
print("/// 出处:ITU-R 建议书 P.839-4,*Rain height model for prediction methods*,")
|
||
print("/// 它在该网格上列出等温线高度。")
|
||
print(f"pub static ZERO_ISOTHERM_HEIGHT_METRES: [[u16; {columns}]; {rows}] = [")
|
||
for row in range(rows):
|
||
values = ", ".join(str(int(value)) for value in metres[row])
|
||
print(f" [{values}],")
|
||
print("];")
|
||
return 0
|
||
|
||
|
||
if __name__ == "__main__":
|
||
raise SystemExit(main())
|