雷达系列 | 如何对国产雷达数据进行衰减订正

文摘   2024-08-27 08:02   北京  

基于pycwr对国产雷达数据进行衰减订正

个人信息

公众号:气python风雨

Image Name

关注我获取更多学习资料,第一时间收到我的Python学习资料,也可获取我的联系方式沟通合作

温馨提示

由于可视化代码过长隐藏,可点击运行Fork查看
若没有成功加载可视化图,点击运行可以查看
ps:隐藏代码在【代码已被隐藏】所在行,点击所在行,可以看到该行的最右角,会出现个三角形,点击查看即可

前言

项目目标

本项目旨在解决气象c波段雷达衰减订正的问题 本来想写使用pyhail对国产雷达进行冰雹反演的,后发现其算法需要雷达数据有十个仰角才可运行。 于是中途改为写衰减订正了。 本文是基于pycwr的源码qc模块搓出来的,原作者没写那咱们补上吧

项目方法

在以下内容中,将详细介绍
1、基于pycwr的三种气象雷达衰减订正
2、如何对pyart的数据进行查看,数据变量如何自由导出、修改、导入
3、如何使用pyart进行简单可视化

安装与导入库

!pip install pycwr  -i https://pypi.mirrors.ustc.edu.cn/simple/
from matplotlib import pyplot as plt
import numpy as np
import cartopy.crs as ccrs 
from pycwr.io import read_auto
import pyart
from pycwr.qc import correct_attenuation_HB,correct_attenuation,pia_from_kdp

读取c波段数据与转格式

PATH='/home/mw/input/pycwr5461/Z_RADR_I_Z9240_20190703101340_O_DOR_SC_CAP.bin.bz2'
PRD = read_auto(PATH)
radar = PRD.ToPyartRadar()

数据信息查看

radar.info()
altitude:
    data: <ndarray of type: float64 and shape: (1,)>
    long_name: Altitude
    standard_name: Altitude
    units: meters
    positive: up
altitude_agl: None
antenna_transition: None
azimuth:
    data: <ndarray of type: float64 and shape: (3240,)>
    units: degrees
    standard_name: beam_azimuth_angle
    long_name: azimuth_angle_from_true_north
    axis: radial_azimuth_coordinate
    comment: Azimuth of antenna relative to true north
elevation:
    data: <ndarray of type: float64 and shape: (3240,)>
    units: degrees
    standard_name: beam_elevation_angle
    long_name: elevation_angle_from_horizontal_plane
    axis: radial_elevation_coordinate
    comment: Elevation of antenna relative to the horizontal plane
fields:
    reflectivity:
        data: <ndarray of type: float32 and shape: (3240, 1000)>
        units: dBZ
        standard_name: equivalent_reflectivity_factor
        long_name: Reflectivity
        coordinates: elevation azimuth range
        _FillValue: -9999.0
    velocity:
        data: <ndarray of type: float32 and shape: (3240, 1000)>
        units: meters_per_second
        standard_name: radial_velocity_of_scatterers_away_from_instrument
        long_name: Mean dopper velocity
        coordinates: elevation azimuth range
        _FillValue: -9999.0
    spectrum_width:
        data: <ndarray of type: float32 and shape: (3240, 1000)>
        units: meters_per_second
        standard_name: doppler_spectrum_width
        long_name: Doppler spectrum width
        coordinates: elevation azimuth range
        _FillValue: -9999.0
fixed_angle:
    data: <ndarray of type: float64 and shape: (9,)>
    long_name: Target angle for sweep
    units: degrees
    standard_name: target_fixed_angle
instrument_parameters:
    pulse_width:
        data: <ndarray of type: float32 and shape: (1,)>
        units: seconds
        comments: Pulse width
        meta_group: instrument_parameters
        long_name: Pulse width
    radar_beam_width_h:
        data: <ndarray of type: float32 and shape: (1,)>
        units: degrees
        meta_group: radar_parameters
        long_name: Antenna beam width H polarization
    radar_beam_width_v:
        data: <ndarray of type: float32 and shape: (1,)>
        units: degrees
        meta_group: radar_parameters
        long_name: Antenna beam width V polarization
    frequency:
        data: <ndarray of type: float32 and shape: (1,)>
        units: s-1
        meta_group: instrument_parameters
        long_name: Radiation frequency
    nyquist_velocity:
        data: <ndarray of type: float64 and shape: (3240,)>
        units: meters_per_second
        comments: Unambiguous velocity
        meta_group: instrument_parameters
        long_name: Nyquist velocity
latitude:
    data: <ndarray of type: float64 and shape: (1,)>
    long_name: Latitude
    standard_name: Latitude
    units: degrees_north
longitude:
    data: <ndarray of type: float64 and shape: (1,)>
    long_name: Longitude
    standard_name: Longitude
    units: degrees_east
nsweeps: 9
ngates: 1000
nrays: 3240
radar_calibration: None
range:
    data: <ndarray of type: float64 and shape: (1000,)>
    units: meters
    standard_name: projection_range_coordinate
    long_name: range_to_measurement_volume
    axis: radial_range_coordinate
    spacing_is_constant: true
    comment: Coordinate variable for range. Range to center of each bin.
    meters_to_center_of_first_gate: 250
    meters_between_gates: 250
scan_rate: None
scan_type: ppi
sweep_end_ray_index:
    data: <ndarray of type: int64 and shape: (9,)>
    long_name: Index of last ray in sweep, 0-based
    units: count
sweep_mode:
    data: <ndarray of type: |S20 and shape: (9,)>
    units: unitless
    standard_name: sweep_mode
    long_name: Sweep mode
    comment: Options are: "sector", "coplane", "rhi", "vertical_pointing", "idle", "azimuth_surveillance", "elevation_surveillance", "sunscan", "pointing", "manual_ppi", "manual_rhi"
sweep_number:
    data: <ndarray of type: int32 and shape: (9,)>
    units: count
    standard_name: sweep_number
    long_name: Sweep number
sweep_start_ray_index:
    data: <ndarray of type: int64 and shape: (9,)>
    long_name: Index of first ray in sweep, 0-based
    units: count
target_scan_rate: None
time:
    data: <ndarray of type: float32 and shape: (3240,)>
    units: seconds since 2019-07-03T18:06:33Z
    standard_name: time
    long_name: time_in_seconds_since_volume_start
    calendar: gregorian
    comment: Coordinate variable for time. Time at the center of each ray, in fractional seconds since the global variable time_coverage_start
metadata:
    Conventions: CF/Radial instrument_parameters
    version: 1.3
    title: 
    institution: 
    references: 
    source: 
    history: 
    comment: 
    instrument_name: 
    original_container: CINRAD/SAB
    site_name: LiaoNing
    radar_name: CINRAD/SA/SB/CB/SC

以下是提供的雷达数据的主要信息的简洁总结:

  • • Altitude: 单个值表示雷达高度,单位为米。

  • • Azimuth: 包含3240个值,表示雷达波束相对于真北方向的角度,单位为度。

  • • Elevation: 包含3240个值,表示雷达波束相对于水平面的角度,单位为度。

  • • Fields:

    • • Reflectivity: 数据形状为(3240, 1000),单位为dBZ,表示反射率。

    • • Velocity: 数据形状为(3240, 1000),单位为m/s,表示平均多普勒速度。

    • • Spectrum Width: 数据形状为(3240, 1000),单位为m/s,表示多普勒谱宽。

  • • Fixed Angle: 包含9个值,表示每个扫掠的目标角度,单位为度。

  • • Instrument Parameters:

    • • Pulse Width: 单个值表示脉冲宽度,单位为秒。

    • • Radar Beam Width H: 单个值表示H极化天线波束宽度,单位为度。

    • • Radar Beam Width V: 单个值表示V极化天线波束宽度,单位为度。

    • • Frequency: 单个值表示辐射频率,单位为s⁻¹。

    • • Nyquist Velocity: 包含3240个值,表示无歧义的速度,单位为m/s。

  • • Latitude and Longitude: 各包含单个值,分别表示纬度和经度,单位分别为度北和度东。

  • • Range: 包含1000个值,表示到测量体积的距离,单位为米。

  • • Scan Type: 表示扫描类型为平面位置指示器(PPI)。

  • • Sweep Information:

    • • Number of Sweeps: 9次扫掠。

    • • Number of Gates per Ray: 每条射线1000个门。

    • • Number of Rays: 3240条射线。

    • • Sweep Mode: 扫掠模式信息。

    • • Sweep Start and End Ray Indices: 每次扫掠的起始和结束射线索引。

  • • Time: 包含3240个值,表示每条射线中心的时间,单位为自2019-07-03T18:06:33Z以来的秒数。

  • • Metadata: 遵循CF/Radial标准,版本1.3,提供了雷达站点名称和雷达名称等信息。

sorted(list(radar.fields))
['reflectivity', 'spectrum_width', 'velocity']

科普

http://kejian2.cmatc.cma.cn/2020/tqradar/study_selftaught2.5.html

在应用新一代天气雷达提供的数据进行预报前,需要了解天气雷达数据覆盖范围,波束展宽,地平线和显示区域的特点和存在的局限性。

新一代天气雷达系统提供较高灵敏度及分辨率的反射率因子、平均径向速度及谱宽三种基数据,从图2.29中可见,新一代天气雷达所探测到的反射率因子数据范围可覆盖0~460km,速度数据范围可覆盖0~230km。基数据通过RPG中的气象水文算法形成的分析产品称为导出产品。一些算法以不同的格式显示基数据,称为无特定算法的导出产品;另一些算法则分析基数据以生成导出产品,称为有特定算法的导出产品。和速度有关的导出产品相应覆盖范围在0~230km,基于反射率因子的算法覆盖范围在0~345km。

在下面的函数中会用到库长这一概念,就扫描半径除以半径的格点数,大伙自个算一算

衰减订正一

correct_attenuation_HB(Ref, a=1.67e-4, b=0.7, gate_length=0.075, thrs=59):
"""
Hitschfeld1954, fillvalue set np.nan
:param Ref: radar ref //dbz [naz, nbins]
:param a: coefficients a
:param b: coefficients b
:param gate_length: bin length //m
:param thrs: thrs //dbz
:return: Zc, pia

corz1,spec_at = correct_attenuation_HB(radar.fields['reflectivity']['data'],
                                            gate_length=0.23)
radar.add_field_like('reflectivity',"specific_attenuation", spec_at)
radar.add_field_like('reflectivity''corrected_reflectivity', corz1)
/opt/conda/lib/python3.9/site-packages/pycwr/qc/attenuation.py:31: RuntimeWarning: overflow encountered in power
  k = a * (10.0 ** ((Ref[:, gate] + ksum) / 10.0)) ** b * 2.0 * gate_length
# create the plot
fig = plt.figure(figsize=(155))
ax1 = fig.add_subplot(131)
display = pyart.graph.RadarDisplay(radar)
display.plot(
    "reflectivity",
    0,
    ax=ax1,
    vmin=0,
    vmax=60.0,
    colorbar_label="",
    title="Raw Reflectivity",
)

ax2 = fig.add_subplot(132)
display.plot(
    "specific_attenuation",
    0,
    vmin=0,
    vmax=1.0,
    colorbar_label="",
    ax=ax2,
    title="Specific Attenuation",
)

ax3 = fig.add_subplot(133)
display = pyart.graph.RadarDisplay(radar)
display.plot(
    "corrected_reflectivity",
    0,
    vmin=0,
    vmax=60.0,
    colorbar_label="",
    ax=ax3,
    title="Corrected Reflectivity",
)

plt.suptitle("Attenuation correction using pycwr", fontsize=16)
plt.show()

衰减订正二

correct_attenuation(ref, wavelength="C", rscale=0.075):

'''Scientific paper: Ośródka, K., Szturc, J., and Jurczyk, A., 2012.
Chain of data quality algorithms for 3-D single-polarization radar
reflectivity (RADVOL-QC system). Meteorol. Appl. (Early View).
rscale : radar gates length(km)
ref :reflectivity factor (dBZ) fillvalue=np.nan'''
return Z_corr, QI

corz2,spec_at2 = correct_attenuation(radar.fields['reflectivity']['data'],wavelength="C", rscale=0.23)
radar.add_field_like('reflectivity',"specific_attenuation2", spec_at2)
radar.add_field_like('reflectivity''corrected_reflectivity2', corz2)
# create the plot
fig = plt.figure(figsize=(155))
ax1 = fig.add_subplot(131)
display = pyart.graph.RadarDisplay(radar)
display.plot(
    "reflectivity",
    0,
    ax=ax1,
    vmin=0,
    vmax=60.0,
    colorbar_label="",
    title="Raw Reflectivity",
)

ax2 = fig.add_subplot(132)
display.plot(
    "specific_attenuation",
    0,
    vmin=0,
    vmax=1.0,
    colorbar_label="",
    ax=ax2,
    title="Specific Attenuation2",
)

ax3 = fig.add_subplot(133)
display = pyart.graph.RadarDisplay(radar)
display.plot(
    "corrected_reflectivity",
    0,
    vmin=0,
    vmax=60.0,
    colorbar_label="",
    ax=ax3,
    title="Corrected Reflectivity2",
)

plt.suptitle("Attenuation correction using pycwr", fontsize=16)
plt.show()

衰减订正三

pia_from_kdp(kdp, dr, gamma=0.08):
"""Retrieving path integrated attenuation from specific differential \
phase (Kdp).
The default value of gamma is based on :cite:Carey2000.
Parameters
----------
kdp : :class:numpy:numpy.ndarray
array specific differential phase
Range dimension must be the last dimension.
dr : gate length (km)
gamma : float
linear coefficient (default value: 0.08) in the relation between
Kdp phase and specific attenuation (alpha)
Returns
-------
output : :class:numpy:numpy.ndarray
array of same shape as kdp containing the path integrated attenuation
"""
就是基于kdp算偏差

    由于手头的c波段雷达数据是单偏振的,  
    
    单偏振没kdp  
    
    那么只能拿另一个双偏振的s波段试试
PATH='/home/mw/input/pycwr5461/Z_RADR_I_Z9898_20190828181529_O_DOR_SAD_CAP_FMT (1).bin.bz2'
PRD = read_auto(PATH)
radar1 = PRD.ToPyartRadar()
sorted(list(radar1.fields))
['cross_correlation_ratio',
 'differential_phase',
 'differential_reflectivity',
 'horizontal_signal_noise_ratio',
 'normalized_coherent_power',
 'reflectivity',
 'specific_differential_phase',
 'spectrum_width',
 'total_power',
 'velocity']

好的,我们看到了我们需要的变量

在这些变量列表中,specific_differential_phase 就是我们所寻找的 KDP 变量

refl_offset = pia_from_kdp(radar1.fields['specific_differential_phase']['data'],0.23)
cal_refl = radar1.fields['reflectivity']['data'] - refl_offset
radar1.add_field_like('reflectivity''refl_offset', refl_offset)
radar1.add_field_like('reflectivity''corrected_reflectivity', cal_refl)
# create the plot
fig = plt.figure(figsize=(155))
ax1 = fig.add_subplot(131)
display = pyart.graph.RadarDisplay(radar1)
display.plot(
    "reflectivity",
    0,
    ax=ax1,
    vmin=0,
    vmax=60.0,
    colorbar_label="",
    title="Raw Reflectivity",
)

ax2 = fig.add_subplot(132)
display.plot(
    "refl_offset",
    0,
    vmin=0,
    vmax=1.0,
    colorbar_label="",
    ax=ax2,
    title="Specific Attenuation3",
)

ax3 = fig.add_subplot(133)
display = pyart.graph.RadarDisplay(radar1)
display.plot(
    "corrected_reflectivity",
    0,
    vmin=0,
    vmax=60.0,
    colorbar_label="",
    ax=ax3,
    title="Corrected Reflectivity3",
)

plt.suptitle("Attenuation correction using pycwr", fontsize=16)
plt.show()

小结

前两种方法计算结果相似,后一种没有可相比,但是清除了不少杂波
大家可用更多文件去试试
pyart库在变量导入导出方面可说是独一无二 希望国内雷达库可以学习学习


气python风雨
主要发一些涉及大气科学的Python文章与个人学习备忘录
 最新文章