带单位的参数
在赤道波动研究中,波数、波长、频率和角频率等物理量计算时,总是会并随麻烦的单位转换问题。
为了简化计算,moisten_ew 使用 pint 模块来管理单位(metpy也是用这个),且绝大部分方法都支持使用单位。
添加单位
要让数据从一堆数字变成带单位的物理量(Quantity),只需要乘上一个单位即可。
import numpy as np
from moisten_ew import unit
temp = 25 * unit.degC # 摄氏度
wind = np.array([5, 10, 15]) * unit('m/s') # 米每秒
乘上单位后,数据会变为 pint.Quantity 类型,可以使用 pint 的各种功能,比如单位转换:
temp_in_k = temp.to('K') # 转换为开尔文
wind_in_kmh = wind.to('km/h') # 转换为公里每小时
更多关于 pint 的使用,可以参考 pint 文档。
模块自带单位
结合赤道波动,本模块添加了两个常用的单位:
zonal_wavenumber:赤道波动的纬向波数,即波动在整个赤道周长上的波数,等价于赤道长度的倒数每米,即2.4953202e-08 / m。cpd:即1/day的简写。
模块的大部分方法中,波数都以 zonal_wavenumber 为基本单位,频率都以 cpd 为基本单位。
哪里该用单位
在模块的方法中,可以使用单位的类型为 Quantity 或 QuantityOrNum,后者表示既可以是带单位的物理量,也可以是纯数字(认为是默认单位)。 例如 butter_filter 滤波函数:
def butter_filter(data: xr.DataArray | np.ndarray,
btype: Literal['lowpass', 'highpass', 'bandpass', 'bandstop'],
freq: QuantityOrNum | tuple[QuantityOrNum, QuantityOrNum] = None,
period: QuantityOrNum | tuple[QuantityOrNum, QuantityOrNum] = None,
sample_freq: QuantityOrNum = None,
sample_interval: QuantityOrNum = None,
axis: int | str = 0, N: int = 3,) -> xr.DataArray | np.ndarray:
...
这里的 freq、period、sample_freq 和 sample_interval 都是 QuantityOrNum 类型,表示可以传入带单位的物理量,也可以传入纯数字,纯数字会被认为是默认单位(频率为 cpd,周期为 day,采样频率为 cpd,采样间隔为 day)。
例如,我想过滤保留 3-8 日周期的信号,数据为 1 日 4 次:
import moisten_ew as mew
filtered_data = mew.butter_filter(
my_data,
btype='bandpass',
period=(3 * mew.unit('day'), 8 * mew.unit('day')), # 带单位的周期
sample_freq=4 * mew.unit('cpd') # 带单位的采样频率
)
当然,这个方法也可以用于不同尺度的滤波,例如有一段 44.1 kHz 采样的音频数据,想滤除高于 20 kHz 的信号:
import moisten_ew as mew
filtered_audio = mew.butter_filter(
audio_data,
btype='lowpass',
freq=20_000 * mew.unit('Hz'), # 带单位的频率
sample_freq=44_100 * mew.unit('Hz') # 带单位的采样频率
)
因此,使用单位更简单直观,避免各种麻烦的单位转换问题。