时空频谱与滤波
wk99_spectrum
wk99_spectrum(
data: xr.DataArray,
lon_name: str = "longitude",
lat_name: str = "latitude",
time_name: str = "time",
window_days: int = 96,
window_overlap_days: int = 64,
max_wavenumber: int = 50,
) -> xr.Dataset
计算 Wheeler-Kiladis 1999 的时空(频率-波数)谱。 输入单个变量的三维数据(时间-纬度-经度), 返回对称、非对称分量的功率谱、背景功率谱及其比值。
参考: WHEELER M, KILADIS G N, 1999. Convectively Coupled Equatorial Waves: Analysis of Clouds and Temperature in the Wavenumber–Frequency Domain[J/OL]. Journal of the Atmospheric Sciences, 56(3): 374-399. 并参考了 NCL 的实现。
Example
>>> # 画出 OLR 数据的 WK99 频率-波数谱
>>>
>>> data = xr.open_dataset("olr.day.mean.nc").olr.sel(lat=slice(20, -20))
>>> res = wk99_spectrum(data, 'lon', 'lat', 'time')
>>> # 选择绘图范围
>>> res = res.sel(wavenumber=slice(-20, 20), freq=slice(0, 1))
>>>
>>> fig = plt.figure(figsize=(8, 4))
>>> for i in range(2):
>>> ax = fig.add_subplot(121 + i)
>>> d = res.spec_ratio.isel(type=i)
>>> ax.contourf(d.wavenumber, d.freq, np.log(d),
... cmap='RdBu_r', levels=np.linspace(-1, 1, 21),
... extend='both')
>>> plt.show()
Parameters:
-
data(xr.DataArray) –输入用于计算的数据,必须为单层的三维数据,维度应包含时间、纬度、经度。
-
lon_name(str, default:'longitude') –DataArray 中经度、纬度、时间维度的名称, by default "longitude", "latitude", "time"
-
lat_name(str, default:'longitude') –DataArray 中经度、纬度、时间维度的名称, by default "longitude", "latitude", "time"
-
time_name(str, default:'longitude') –DataArray 中经度、纬度、时间维度的名称, by default "longitude", "latitude", "time"
-
window_days(int, default:96) –循环窗口的天数, by default 96
-
window_overlap_days(int, default:64) –窗口间的重叠天数, by default 64
-
max_wavenumber(int, default:50) –输出的最大波数范围,单位为 zonal_wavenumber,
Returns:
-
xr.DataSet–返回一个包含了三个变量的数据集,分别为:
- spec_origin: 原始的频率-波数谱,包含对称与非对称分量
- spec_bg: 背景谱,由对称与非对称分量的平均值计算得到,并经过平滑处理
- spec_ratio: 原始谱与背景谱的比值
FilterArea
FilterArea(shape: Polygon | MultiPolygon, attributes: FilterAreaAttributes)
用于表示FFT滤波区域的类,包含滤波区域的几何形状和属性信息。
给定滤波区域的多边形范围与属性,创建一个滤波区域实例。
区域多边形的坐标分别为:
- x 轴:纬向波数,单位为 'zonal_wavenumber'
- y 轴:频率,单位为 'cpd'
Parameters:
-
shape(Polygon | MultiPolygon) –滤波区域的几何形状
-
attributes(FilterAreaAttributes) –滤波区域的属性信息,将作为描述滤波结果的元数据
attributes
instance-attribute
attributes = attributes
区域的属性信息
shape
instance-attribute
shape = shape
区域的形状
to_cpd
staticmethod
to_cpd(val: float) -> float
将频率从 meter * zonal_wavenumber / second 转为 cpd
FilterAreaAttributes
dataclass
FilterAreaAttributes(
name: str,
description: str = "",
parameters: dict[str, QuantityOrNum] = lambda: {}(),
is_exclusive: bool = False,
union_from: list[FilterAreaAttributes] = list(),
intersection_from: list[FilterAreaAttributes] = list(),
different: dict[str, FilterAreaAttributes] = lambda: {}(),
)
滤波区域的属性信息类,用于描述滤波区域的元数据。
to_json_str
to_json_str(indent=2) -> str
将属性转换为 JSON 字符串
RectangleFilterArea
RectangleFilterArea(
min_wavenumber: QuantityOrNum,
max_wavenumber: QuantityOrNum,
min_frequency: QuantityOrNum,
max_frequency: QuantityOrNum,
)
Bases: FilterArea
矩形的FFT滤波区域
创建一个 FFT 纬向波数-频率频谱中的矩形滤波区域。
Parameters:
-
min_wavenumber(QuantityOrNum) –矩形在纬向波数方向的两个边界值,默认单位为 'zonal_wavenumber'。
-
max_wavenumber(QuantityOrNum) –矩形在纬向波数方向的两个边界值,默认单位为 'zonal_wavenumber'。
-
min_frequency(QuantityOrNum) –矩形在频率方向的两个边界值,默认单位为 'cpd'。
-
max_frequency(QuantityOrNum) –矩形在频率方向的两个边界值,默认单位为 'cpd'。
EllipseFilterArea
EllipseFilterArea(
center_wavenumber: QuantityOrNum,
center_frequency: QuantityOrNum,
wavenumber_radius: QuantityOrNum,
freq_radius: QuantityOrNum,
)
Bases: FilterArea
椭圆的FFT滤波区域
创建一个 FFT 纬向波数-频率频谱中的椭圆滤波区域。
Parameters:
-
center_wavenumber(QuantityOrNum) –椭圆中心在纬向波数方向的坐标,默认单位为 'zonal_wavenumber'。
-
center_frequency(QuantityOrNum) –椭圆中心在频率方向的坐标,默认单位为 'cpd'。
-
wavenumber_radius(QuantityOrNum) –椭圆在波数方向的半径,默认单位为 'zonal_wavenumber'。
-
freq_radius(QuantityOrNum) –椭圆在频率方向的半径,默认单位为 'cpd'。
KelvinFilterArea
KelvinFilterArea(
min_depth: QuantityOrNum = 8,
max_depth: QuantityOrNum = 90,
min_freq: QuantityOrNum = 1 / 30,
max_freq: QuantityOrNum = 0.4,
min_wavenumber: QuantityOrNum = 1,
max_wavenumber: QuantityOrNum = 14,
g: QuantityOrNum = EARTH_GRAVITY,
beta: QuantityOrNum = ROSSBY_PARAMETER_ON_EQUATOR,
)
Bases: FilterArea
创建一个 Kelvin 波的 FFT 滤波区域, 用于过滤出符合 Kelvin 波频散关系的信号。
Parameters:
-
min_depth(QuantityOrNum, default:8) –相当深度范围, 默认分别为 8 m 和 90 m
-
max_depth(QuantityOrNum, default:8) –相当深度范围, 默认分别为 8 m 和 90 m
-
min_freq(QuantityOrNum, default:1 / 30) –频率范围, 默认为 1/30 cpd 和 0.4 cpd
-
max_freq(QuantityOrNum, default:1 / 30) –频率范围, 默认为 1/30 cpd 和 0.4 cpd
-
min_wavenumber(QuantityOrNum, default:1) –纬向波数范围, 默认为 1 和 14
-
max_wavenumber(QuantityOrNum, default:1) –纬向波数范围, 默认为 1 和 14
-
g(QuantityOrNum, default:EARTH_GRAVITY) –重力加速度, by default EARTH_GRAVITY
-
beta(QuantityOrNum, default:ROSSBY_PARAMETER_ON_EQUATOR) –赤道上的罗斯贝参数, by default ROSSBY_PARAMETER_ON_EQUATOR
MRGFilterArea
MRGFilterArea(
min_depth: QuantityOrNum = 8,
max_depth: QuantityOrNum = 90,
min_freq: QuantityOrNum = 0.1,
max_freq: QuantityOrNum = 0.35,
min_wavenumber: QuantityOrNum = -10,
max_wavenumber: QuantityOrNum = -1,
g: QuantityOrNum = EARTH_GRAVITY,
beta: QuantityOrNum = ROSSBY_PARAMETER_ON_EQUATOR,
)
Bases: FilterArea
创建一个 Mixed Rossby-Gravity 波的 FFT 滤波区域, 用于过滤出符合 MRG 波频散关系的信号。 注意,此滤波区域包含西传 MRG 波和东传 MRG 波,只需要设置对应的波数范围即可。
>>> # 西传 MRG 波滤波区域 (默认参数)
>>> area = mew.MRGFilterArea(min_wavenumber=-10, max_wavenumber=-1)
>>> # 东传 MRG 波滤波区域 (东传 MRG 波频率更大)
>>> area = mew.MRGFilterArea(min_wavenumber=1, max_wavenumber=10,
max_freq=0.85)
>>> # 或者两者都包含
>>> area = mew.MRGFilterArea(min_wavenumber=-10, max_wavenumber=10,
max_freq=0.85)
Parameters:
-
min_depth(QuantityOrNum, default:8) –相当深度范围, 默认分别为 8 m 和 90 m
-
max_depth(QuantityOrNum, default:8) –相当深度范围, 默认分别为 8 m 和 90 m
-
min_freq(QuantityOrNum, default:0.1) –频率范围, 默认为 0.1 cpd 和 0.35 cpd
-
max_freq(QuantityOrNum, default:0.1) –频率范围, 默认为 0.1 cpd 和 0.35 cpd
-
min_wavenumber(QuantityOrNum, default:-10) –纬向波数范围, 默认为 -10 和 -1
-
max_wavenumber(QuantityOrNum, default:-10) –纬向波数范围, 默认为 -10 和 -1
-
g(QuantityOrNum, default:EARTH_GRAVITY) –重力加速度, by default EARTH_GRAVITY
-
beta(QuantityOrNum, default:ROSSBY_PARAMETER_ON_EQUATOR) –赤道上的罗斯贝参数, by default ROSSBY_PARAMETER_ON_EQUATOR
ERFilterArea
ERFilterArea(
n: int = 1,
min_depth: QuantityOrNum = 8,
max_depth: QuantityOrNum = 90,
min_freq: QuantityOrNum = 1 / 60,
max_freq: QuantityOrNum = 1 / 5,
min_wavenumber: QuantityOrNum = -10,
max_wavenumber: QuantityOrNum = 0,
g: QuantityOrNum = EARTH_GRAVITY,
beta: QuantityOrNum = ROSSBY_PARAMETER_ON_EQUATOR,
)
Bases: FilterArea
创建一个 Equatorial Rossby 波的 FFT 滤波区域, 用于过滤出符合 ER 波频散关系的信号。 因为 ER 波为西传波,所以波数需为负数。
Parameters:
-
n(int, default:1) –埃尔米特多项式的阶数 n,需大于等于1,默认为 1。
-
min_depth(QuantityOrNum, default:8) –相当深度范围, 默认分别为 8 m 和 90 m
-
max_depth(QuantityOrNum, default:8) –相当深度范围, 默认分别为 8 m 和 90 m
-
min_freq(QuantityOrNum, default:1 / 60) –频率范围, 默认为 1/60 cpd 和 1/5 cpd
-
max_freq(QuantityOrNum, default:1 / 60) –频率范围, 默认为 1/60 cpd 和 1/5 cpd
-
min_wavenumber(QuantityOrNum, default:-10) –纬向波数范围, 默认为 -10 和 0
-
max_wavenumber(QuantityOrNum, default:-10) –纬向波数范围, 默认为 -10 和 0
-
g(QuantityOrNum, default:EARTH_GRAVITY) –重力加速度, by default EARTH_GRAVITY
-
beta(QuantityOrNum, default:ROSSBY_PARAMETER_ON_EQUATOR) –赤道上的罗斯贝参数, by default ROSSBY_PARAMETER_ON_EQUATOR
IGFilterArea
IGFilterArea(
n: int = 1,
min_depth: QuantityOrNum = 12,
max_depth: QuantityOrNum = 50,
min_freq: QuantityOrNum = 0.3,
max_freq: QuantityOrNum = 0.7,
min_wavenumber: QuantityOrNum = -15,
max_wavenumber: QuantityOrNum = -1,
g: QuantityOrNum = EARTH_GRAVITY,
beta: QuantityOrNum = ROSSBY_PARAMETER_ON_EQUATOR,
)
Bases: FilterArea
创建一个 Inertio Gravity 波的 FFT 滤波区域, 用于过滤出符合 IG 波频散关系的信号。 注意,此滤波区域包含西传 IG 波和东传 IG 波,只需要设置对应的波数范围即可。
>>> # 西传 IG 波滤波区域 (默认参数)
>>> area = mew.IGFilterArea(min_wavenumber=-15, max_wavenumber=-1)
>>> # 东传 IG 波滤波区域
>>> area = mew.IGFilterArea(min_wavenumber=1, max_wavenumber=15)
>>> # 或者两者都包含
>>> area = mew.IGFilterArea(min_wavenumber=-15, max_wavenumber=15)
Parameters:
-
n(int, default:1) –埃尔米特多项式的阶数 n,需大于等于1,默认为 1。
-
min_depth(QuantityOrNum, default:12) –相当深度范围, 默认分别为 12 m 和 50 m
-
max_depth(QuantityOrNum, default:12) –相当深度范围, 默认分别为 12 m 和 50 m
-
min_freq(QuantityOrNum, default:0.3) –频率范围, 默认为 0.3 cpd 和 0.7 cpd
-
max_freq(QuantityOrNum, default:0.3) –频率范围, 默认为 0.3 cpd 和 0.7 cpd
-
min_wavenumber(QuantityOrNum, default:-15) –纬向波数范围, 默认为 -15 和 -1
-
max_wavenumber(QuantityOrNum, default:-15) –纬向波数范围, 默认为 -15 和 -1
-
g(QuantityOrNum, default:EARTH_GRAVITY) –重力加速度, by default EARTH_GRAVITY
-
beta(QuantityOrNum, default:ROSSBY_PARAMETER_ON_EQUATOR) –赤道上的罗斯贝参数, by default ROSSBY_PARAMETER_ON_EQUATOR
MJOFilterArea
MJOFilterArea(
min_freq: QuantityOrNum = 1 / 96,
max_freq: QuantityOrNum = 1 / 30,
min_wavenumber: QuantityOrNum = 0.5,
max_wavenumber: QuantityOrNum = 5,
)
Bases: RectangleFilterArea
创建一个 MJO 的 FFT 滤波区域,用于过滤出符合 MJO 波频散关系的信号。 此滤波区域为矩形区域。
Parameters:
-
min_freq(QuantityOrNum, default:1 / 96) –频率范围, 默认为 1/90 cpd (96日周期) 和 1/30 cpd (30日周期)
-
max_freq(QuantityOrNum, default:1 / 96) –频率范围, 默认为 1/90 cpd (96日周期) 和 1/30 cpd (30日周期)
-
min_wavenumber(QuantityOrNum, default:0.5) –纬向波数范围, 默认为 0.5 和 5
-
max_wavenumber(QuantityOrNum, default:0.5) –纬向波数范围, 默认为 0.5 和 5
TDFilterArea
TDFilterArea(
min_freq: QuantityOrNum = 1 / 6,
max_freq: QuantityOrNum = 1 / 2.5,
min_wavenumber: QuantityOrNum = -18,
max_wavenumber: QuantityOrNum = -8,
)
Bases: RectangleFilterArea
创建一个 Tropical depression type 波的 FFT 滤波区域, 用于过滤出符合 TD-type 波频散关系的信号。 此滤波区域为矩形区域。
Parameters:
-
min_freq(QuantityOrNum, default:1 / 6) –频率范围, 默认为 1/6 cpd (6日周期) 和 1/2.5 cpd (2.5日周期)
-
max_freq(QuantityOrNum, default:1 / 6) –频率范围, 默认为 1/6 cpd (6日周期) 和 1/2.5 cpd (2.5日周期)
-
min_wavenumber(QuantityOrNum, default:-18) –纬向波数范围, 默认为 -18 和 -8
-
max_wavenumber(QuantityOrNum, default:-18) –纬向波数范围, 默认为 -18 和 -8
fft_time_lon_area_filter
fft_time_lon_area_filter(
data: xr.DataArray,
filter_area: FilterArea | Polygon | MultiPolygon,
lon_name: str | int = "longitude",
time_name: str | int = "time",
time_window: bool = True,
time_window_alpha: float = 0.1,
lon_window: bool = False,
lon_window_alpha: float = 0.1,
) -> xr.DataArray
对 xarray.DataArray 数据进行时间-经度二维FFT区域滤波,保留滤波区域的信号。 配合 FilterArea 使用,例如提取 Kelvin 波的信号:
Example
>>> uwnd = xr.open_dataarray("uwnd.nc") # (time, lat, lon)
>>>
>>> # 提取 Kelvin 波信号
>>> kelvin_area = mew.KelvinFilterArea()
>>> kelvin_uwnd = mew.fft_time_lon_area_filter(
... uwnd, kelvin_area,
... lon_name="lon", time_name="time"
... )
>>>
>>> # 提取符合波数 3~10 zonal_wavenumber,频率 0.2~0.8 cpd 的信号
>>> rect_area = mew.RectangleFilterArea(
... min_wavenumber=3, max_wavenumber=10,
... min_freq=0.2, max_freq=0.8
... )
>>> rect_uwnd = mew.fft_time_lon_area_filter(
... uwnd, rect_area,
... lon_name="lon", time_name="time"
... )
Parameters:
-
data(xr.DataArray) –需要滤波的数据,必须包含经度与时间维度。
-
filter_area(FilterArea | Polygon | MultiPolygon) –滤波区域,将保留区域内的信号,可以是 FilterArea 实例, 或 shapely 的 Polygon / MultiPolygon 多边形实例, 多边形的平面坐标需要使用以下单位:
- x 轴:纬向波数,单位为 'zonal_wavenumber'
- y 轴:频率,单位为 'cpd'
-
lon_name(str | int, default:'longitude') –数据中的经度维度名称或索引, by default "longitude"
-
time_name(str | int, default:'time') –数据中的时间维度名称或索引, by default "time"
-
time_window(bool, default:True) –是否给数据的时间维度上加窗, by default True
-
time_window_alpha(float, default:0.1) –加窗时使用的 Tukey 窗函数的 alpha 参数, by default 0.1
-
lon_window(bool, default:False) –是否给数据的经度维度上加窗, 建议非全球数据(不头尾循环)加窗。 by default False
-
lon_window_alpha(float, default:0.1) –加窗时使用的 Tukey 窗函数的 alpha 参数, by default 0.1
Returns:
-
xr.DataArray–返回滤波后的数据,数据结构与输入 data 保持一致。