
MeteoInfoLab可以通过写脚本读取BUFR格式数据,详见此公众号的文章读取BUFR、PREPBUFR数据。最近有大气物理所的专家指出最新的北斗探空BUFR格式数据无法读取,因此需要更新软件提供相关功能。
BUFR格式是表格驱动的,除了WMO的标准表格,各区域中心可以创建自己的表格,因此加入相关BUFR数据的特有表格是正确读取数据的基础。
北斗探空系统是中国自主研发的高空气象探测系统,使用北斗导航系统提供的定位和传输功能,采用“云+端”地—空物联传输模式,支持“上升—平漂—下降”三段式观测,单次施放可获取两次大气廓线数据。2025年8月,北斗探空系统通过业务升级换代专家论证,完成全国观测站网布局优化。截至2025年10月,全国120个探空站完成北斗系统切换,数据全面融入气象核心业务应用。
北斗探空系统综合精度超过GPS技术,完全解决了我国高空气象探测系统的自主性和安全性问题。
收集了北斗探空的示例数据文件和相关Table B和Table D文件,并对表格格式进行了改写,以符合MeteoInfo BUFR文件读取的要求。在MeteoInfoLab启动时动态加载这些表格文件,这样就解决了北斗探空BUFR数据读取的问题。刚刚将MeteoInfo升级到了4.1.4版本,此版本可以正常读取北斗探空BUFR数据文件,但目前测试很有限,如果大家发现有新的问题欢迎沟通交流。
这里给出一个简单的例子:
# Open bufr data file and read data
fn = r'D:\Temp\bufr\T_UPAR_I_59981_20251012111705_O_TEMP-P-50-SEC_2025101300.BIN'
f = addfile(fn, keepopen=True)
obs = f.obs
print(obs.varnames)
lon = obs.Longitude_high_accuracy.values
lat = obs.Latitude_high_accuracy.values
seq = obs.seq6
print('#############')
print(seq.varnames)
temp = seq.Temperature_air_temperature_2.values
u = seq.u_component.values
v = seq.v_component.values
height = seq.Height_10.values
f.close()
ws = meteolib.wind_speed(u, v)
s = slice(None, None, 20)
barbs(temp[s]-1, height[s], u[s], v[s], ws[s], size=10, cmap='MPL_rainbow')
colorbar(shrink=0.8, label='Wind speed (m/s)')
plot(temp, height, color='b')
xlabel('Temperature (K)')
ylabel('Height (m)')
代码运行结果:

具体技术问题可以加入MeteoInfo QQ群(808554605)沟通交流。
上面的代码和之前BUFR数据文件读取的帖子里区别比较大,是因为对数据文件里的变量和具体数组的读取方式也做了更新,将变量名也作为属性放入了文件和结构变量里,这样除了可以通过中括号里放变量名字符串的方式获取变量(例如:f['obs']),也可以通过Python对象属性方式小数点加变量名获取变量(例如:f.obs)。从一个变量里读取所有数据可以用变量的values属性。
以上面的文件为例:
先用addfile函数加载数据文件形成数据文件对象f,用两种方式从f中获取obs变量:
>>> fn = r'D:\Temp\bufr\T_UPAR_I_59981_20251012111705_O_TEMP-P-50-SEC_2025101300.BIN'
>>> f = addfile(fn, keepopen=True)
>>> f['obs']
obs):
obs: coordinates = "Latitude_high_accuracy Longitude_high_accuracy Height_of_station_ground_above_mean_sea_level Height Height-2 Height-3 Height-4 Height-5 Height-6 Height-7 Height-8 Height-9 Height-10 Latitude_high_accuracy-2 Longitude_high_accuracy-2 Height-11 Latitude_high_accuracy-3 Longitude_high_accuracy-3 "
>>> f.obs
obs):
obs: coordinates = "Latitude_high_accuracy Longitude_high_accuracy Height_of_station_ground_above_mean_sea_level Height Height-2 Height-3 Height-4 Height-5 Height-6 Height-7 Height-8 Height-9 Height-10 Latitude_high_accuracy-2 Longitude_high_accuracy-2 Height-11 Latitude_high_accuracy-3 Longitude_high_accuracy-3 "
>>>
从obs变量里获取经度变量并读取其中的数组:
>>> obs['Longitude_high_accuracy'][:]
array([112.33220000])
>>> obs.Longitude_high_accuracy.values
array([112.33220000])
>>>
还需要说明的是由于BUFR文件中有些变量名称包含了"-"、"#"等Python变量名不支持的特殊字符,在读取时自动进行了处理,因此之前的一些BUFR数据读取的代码可能需要修改。例如此公众号的文章读取BUFR、PREPBUFR数据帖子里的第二个例子可以做如下修改:
fn = 'D:/Temp/bufr/prepbufr.gdas.20230325.t00z.nr'
f = addfile(fn, keepopen=True)
obs = f['SATWND']
print(obs.varnames)
lon = obs.XOB_3.values
lat = obs.YOB_3.values
sid = obs.SID_3.values
typ = obs.TYP_3.values
v = obs.P_INFO_PRESSURE_INFORMATION
vv = v.P_EVENT_PRESSURE_EVENT_SEQUENCE
vvv = vv.POB_3
data = vvv[0]
f.close()
#Plot
axesm()
geoshow('country')
layer = scatter(lon, lat, data, size=2, edgecolor=None, zorder=0)
colorbar(layer)
title('Bufr data example')

如果BUFR文件中某个变量名中有中文字符的话就不做变量名的转换了,只能用方括号里变量名字符的形式获取变量:
fn = r'D:\Temp\bufr\Z_SURF_I_59854_20180814232000_O_AWS-RSD-MM_FTM.BIN'
f = addfile(fn, keepopen=True)
obs = f.obs
print(obs.varnames)
lon = obs.Longitude_high_accuracy.values
lat = obs.Latitude_high_accuracy.values
print('Longitude: {}; Latitude: {}'.format(lon, lat))
st_id = obs.WMO_station_number.values
itype = obs[u'雨滴谱的设备类型'][:]
year = obs.Year[:][0]
month = obs.Month[:][0]
day = obs.Day[:][0]
hour = obs.Hour[:][0]
minute = obs.Minute[:][0]
t = datetime.datetime(year, month, day, hour, minute)
seq1 = obs.seq1
print(seq1.varnames)
ti = seq1.Time_increment.values
sti = seq1.Short_time_increment.values
print(ti, sti)
seq2 = seq1.seq2
print(seq2.varnames)
seq3 = seq2.seq3
print(seq3.varnames)
n_raindrop = seq3[u'雨滴个数'][:]
id_raindrop = seq3[u'谱图数据编号'][:]
f.close()
scatter(id_raindrop, n_raindrop, s=4, edgecolor=None, facecolor='b')
xlabel(u'谱图数据编号', fontname=u'宋体')
ylabel(u'雨滴个数', fontname=u'宋体')

用属性方式获取变量的好处是可以用MeteoInfoLab的代码提示功能,简化写程序的过程,这个需要在写代码过程中运行部分相关代码(例如打开文件生成数据文件对象的代码,这样才能利用数据文件对象的代码提示功能)
END
声明:欢迎转载、转发。气象学家公众号转载信息旨在传播交流,其内容由作者负责,不代表本号观点。文中部分图片来源于网络,如涉及内容、版权和其他问题,请联系小编处理。