您的位置:

Python CINRAD雷达数据解析与可视化工具

一、CINRAD雷达的基本概述

在介绍Python CINRAD雷达数据解析与可视化工具之前,我们首先需要了解一下CINRAD雷达的基本概念。CINRAD雷达是中国自主研发的一种天气雷达,被广泛应用于气象、公路、航空、水利等领域。CINRAD雷达可以获取雷达反射率因子、速度以及谱宽等数据,这些数据对于气象预报和灾害预警具有重要的意义。

CINRAD雷达系统主要由雷达机体、天线、发射机和接收机等组成。雷达机体位于地面附近,通过雷达天线向周围发射电磁波,当电磁波遇到云层等物体时,会被反射回来并被接收机接收。

二、Python CINRAD雷达数据解析的基本流程

Python CINRAD雷达数据解析的基本流程分为数据读取、头文件解析、数据解压和数据可视化几个步骤。

1. 数据读取

我们可以使用Python中的open函数来打开CINRAD雷达数据文件,并用read()函数读取文件内容。读取的文件内容为二进制格式的数据,我们需要进行解析。

import numpy as np

filename = 'Z_RADR_I_Z9857_20190809134600_O_DOR_SA_CAP.bin'
with open(filename, 'rb') as f:
    data = f.read()

2. 头文件解析

在CINRAD雷达数据中,头文件中包含了一些与数据本身相关的元信息。我们需要使用Python来解析这些信息,例如雷达反射率因子、速度和谱宽等数据的分辨率、扫描方式以及探测距离等信息。

header = np.frombuffer(data, dtype='>i4', count=45)
element_number = header[3] #雷达反射率因子、速度和谱宽等数据的元素数
range_number = header[4] #距离元素数
azimuth_number = header[6] #方位角元素数
range_scale = header[7] / 1000.0 #距离分辨率
azimuth_scale = header[8] / 1000.0 #方位角分辨率
elevation_number = 1
elevation_scale = 1.0

3. 数据解压

在CINRAD雷达数据中,每个元素都被压缩为两个字节。我们需要使用Python对数据进行解压缩,并转换为真实的数据。雷达反射率因子、速度和谱宽等数据都需要进行解压缩,并乘以各自的比例因子得到真实的数据值。

data_offset = header[11] #数据起始点偏移(byte)
data_block = data[data_offset:]
data_array = np.frombuffer(data_block, dtype='>u2')
data_array = data_array.astype('float32')
data_array[data_array == 0] = np.nan
reflectivity = (data_array[0:element_number*range_number*azimuth_number]
               .reshape((azimuth_number, range_number, element_number))
               .swapaxes(0,1))
reflectivity = reflectivity * header[19] + header[20]
velocity = (data_array[element_number*range_number*azimuth_number:
                       element_number*range_number*azimuth_number*2]
           .reshape((azimuth_number, range_number, element_number))
           .swapaxes(0,1))
velocity = velocity * header[21] + header[22]
spectrum_width = (data_array[element_number*range_number*azimuth_number*2:
                              element_number*range_number*azimuth_number*3]
                  .reshape((azimuth_number, range_number, element_number))
                  .swapaxes(0,1))
spectrum_width = spectrum_width * header[23] + header[24]

4. 数据可视化

最后,我们可以使用Python的数据可视化工具例如matplotlib或者basemap将CINRAD雷达数据进行可视化。我们可以将雷达反射率因子、速度和谱宽等数据绘制成不同的图像,以便于我们对数据进行分析。

import matplotlib.pyplot as plt

range_array = np.arange(0, range_number) * range_scale
azimuth_array = np.arange(0, azimuth_number) * azimuth_scale
azimuth_mesh, range_mesh = np.meshgrid(azimuth_array, range_array)

#雷达反射率因子
plt.figure()
plt.pcolormesh(azimuth_mesh, range_mesh/1000.0,
               reflectivity.transpose(), cmap='jet', vmin=-32, vmax=94)
plt.xlabel('Azimuth (degree)')
plt.ylabel('Range (km)')
plt.title('Reflectivity')
plt.colorbar()

#速度
plt.figure()
plt.pcolormesh(azimuth_mesh, range_mesh/1000.0,
               velocity.transpose(), cmap='seismic', vmin=-30, vmax=30)
plt.xlabel('Azimuth (degree)')
plt.ylabel('Range (km)')
plt.title('Velocity')
plt.colorbar()

#谱宽
plt.figure()
plt.pcolormesh(azimuth_mesh, range_mesh/1000.0,
               spectrum_width.transpose(), cmap='plasma', vmin=0, vmax=8)
plt.xlabel('Azimuth (degree)')
plt.ylabel('Range (km)')
plt.title('Spectrum Width')
plt.colorbar()

plt.show()

三、Python CINRAD雷达数据解析与可视化实例

通过以上的步骤,我们可以使用Python CINRAD雷达数据解析与可视化工具来对CINRAD雷达数据进行处理。下面我们以解析通州站雷达2019年8月9日13时46分的数据为例,进行数据可视化。

import numpy as np
import matplotlib.pyplot as plt

filename = 'Z_RADR_I_Z9857_20190809134600_O_DOR_SA_CAP.bin'
with open(filename, 'rb') as f:
    data = f.read()

header = np.frombuffer(data, dtype='>i4', count=45)
element_number = header[3] #雷达反射率因子、速度和谱宽等数据的元素数
range_number = header[4] #距离元素数
azimuth_number = header[6] #方位角元素数
range_scale = header[7] / 1000.0 #距离分辨率
azimuth_scale = header[8] / 1000.0 #方位角分辨率
elevation_number = 1
elevation_scale = 1.0

data_offset = header[11] #数据起始点偏移(byte)
data_block = data[data_offset:]
data_array = np.frombuffer(data_block, dtype='>u2')
data_array = data_array.astype('float32')
data_array[data_array == 0] = np.nan

reflectivity = (data_array[0:element_number*range_number*azimuth_number]
               .reshape((azimuth_number, range_number, element_number))
               .swapaxes(0,1))
reflectivity = reflectivity * header[19] + header[20]

velocity = (data_array[element_number*range_number*azimuth_number:
                       element_number*range_number*azimuth_number*2]
           .reshape((azimuth_number, range_number, element_number))
           .swapaxes(0,1))
velocity = velocity * header[21] + header[22]

spectrum_width = (data_array[element_number*range_number*azimuth_number*2:
                              element_number*range_number*azimuth_number*3]
                  .reshape((azimuth_number, range_number, element_number))
                  .swapaxes(0,1))
spectrum_width = spectrum_width * header[23] + header[24]

range_array = np.arange(0, range_number) * range_scale
azimuth_array = np.arange(0, azimuth_number) * azimuth_scale
azimuth_mesh, range_mesh = np.meshgrid(azimuth_array, range_array)

#雷达反射率因子
plt.figure()
plt.pcolormesh(azimuth_mesh, range_mesh/1000.0,
               reflectivity.transpose(), cmap='jet', vmin=-32, vmax=94)
plt.xlabel('Azimuth (degree)')
plt.ylabel('Range (km)')
plt.title('Reflectivity')
plt.colorbar()

#速度
plt.figure()
plt.pcolormesh(azimuth_mesh, range_mesh/1000.0,
               velocity.transpose(), cmap='seismic', vmin=-30, vmax=30)
plt.xlabel('Azimuth (degree)')
plt.ylabel('Range (km)')
plt.title('Velocity')
plt.colorbar()

#谱宽
plt.figure()
plt.pcolormesh(azimuth_mesh, range_mesh/1000.0,
               spectrum_width.transpose(), cmap='plasma', vmin=0, vmax=8)
plt.xlabel('Azimuth (degree)')
plt.ylabel('Range (km)')
plt.title('Spectrum Width')
plt.colorbar()

plt.show()