爱气象,爱气象家园! 

气象家园

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

搜索
查看: 896|回复: 1

尝试从01开始的读取雷达二进制文件并输出

[复制链接]

新浪微博达人勋

发表于 2022-9-20 16:20:19 | 显示全部楼层 |阅读模式

登录后查看更多精彩内容~

您需要 登录 才可以下载或查看,没有帐号?立即注册 新浪微博登陆

x
本帖最后由 青羽 于 2022-9-20 16:21 编辑

因为工作原因,我需要用程序读取如 "Z_RADR_I_Z9871_20220819181133_O_DOR_CC_CAP_FMT.bin" 这样的雷达文件,并将其包含的信息输出为文字+图片。在工作开始之初,我看到大名鼎鼎的pycinrad,但是安装失败。报错提示是他依赖于cartopy,而cartopy依赖于proj和GEOs。而这两个东西安装及其麻烦,体验非常糟糕,除了使用anaconda几乎不能无痛安装。我本人因为编程洁癖,特别讨厌使用anaconda和其系列产品,他总是在我控制范围外下载我不需要的依赖,搞的环境臃肿。
Snipaste_2022-09-20_15-36-36.png
而且,proj和GEOs的地图库似乎存在偏移,我不清楚他们使用的是否是国家基础地理信息中心审核的地图,也不清楚这个问题到底是地图图层就错误了还是在编程过程中投影方式的放缩错误。总之,我就是因为和同事在实际业务工作中发现了地图偏移问题(几乎偏离的半个镇)才想要自己读取雷达文件尝试修正这个错误的,获得正确的雷达图像用以指导预报业务。
下面是我自己根据雷达格式文件,自己尝试解读的思路,本帖会不定时更新,欢迎各位老师批评指正。
1661494926271.png 1661501584641.png 1661498064855.png 1661502147901.png 1661503691051.png 1661744360173.png 1661754666513.png 1661744806930.png 1661755897627.png 1661760228155.png 1661761234746.png
使用Python读取对应二进制字节的代码如下:

  1. import struct
  2. print('魔术字  :', struct.unpack('4s', b'\x52\x53\x54\x4D'))
  3. print('主版本号:', struct.unpack('h', b'\x02\x00'))
  4. print('次版本号:', struct.unpack('h', b'\x00\x00'))
  5. print('文件类型:', struct.unpack('i', b'\x01\x00\x00\x00'))
  6. print('产品类型:', struct.unpack('>L', b'\x00\x00\x00\x80')) # 产品类型 #存疑

  7. print('站号    :', struct.unpack('5s', b'\x5A\x39\x38\x37\x31'))  # 应该读8字节,为了代码美观只写5字节
  8. print('站名    :', struct.unpack('13s', b'\x4b\x75\x6e\x4d\x69\x6e\x67\x5f\x5A\x39\x38\x37\x31'))
  9. print('纬度    :', struct.unpack('f', b'\xD0\x69\xC8\x41'))
  10. print('经度    :', struct.unpack('f', b'\x1B\x28\xCD\x42'))
  11. print('天线高度:', struct.unpack('i', b'\xB4\x09\x00\x00'))
  12. print('地面高度:', struct.unpack('i', b'\x9A\x09\x00\x00')) # 雷达塔头地面高度
  13. print('工作频率:', struct.unpack('f', b'\x00\xb0\xa9\x45'))
  14. print('水平波束宽度:', struct.unpack('f', b'\x1f\x85\x8b\x3f'))
  15. print('垂直波束宽度:', struct.unpack('f', b'\x1f\x85\x8b\x3f'))
  16. print('RDA版本号:', struct.unpack('i', b'\x00\x00\x02\x00'))
  17. print('雷达类型:', struct.unpack('h', b'\x23\x00')) # 是CC雷达

  18. print('任务名称:', struct.unpack('5s', b'\x56\x43\x50\x32\x31'))
  19. print('任务描述:', struct.unpack('10s', b'\x53\x55\x4e\x20\x43\x52\x45\x41\x54\x45'))
  20. print('极化方式:', struct.unpack('i', b'\x01\x00\x00\x00'))     # 水平极化
  21. print('扫描任务类型:', struct.unpack('i', b'\x00\x00\x00\x00')) # 体扫
  22. print('脉冲宽度:', struct.unpack('i', b'\xe8\x03\x00\x00'))
  23. print('扫描开始时间:', struct.unpack('i', b'\x55\xd2\xff\x62')) # 2022-08-20 02:11:33
  24. print('扫描层数:', struct.unpack('i', b'\x0b\x00\x00\x00'))
  25. print('水平通道噪声:', struct.unpack('f', b'\x52\xb8\x9e\x41'))
  26. print('垂直通道噪声:', struct.unpack('f', b'\xf0\x23\x74\xc9'))
  27. print('水平通道标定值:', struct.unpack('f', b'\xec\x51\xd4\x41'))
  28. print('垂直通道标定值:', struct.unpack('f', b'\xf0\x23\x74\xc9'))
  29. print('水平通道噪声温度:', struct.unpack('f', b'\x56\x2a\x14\x43'))
  30. print('垂直通道噪声温度:', struct.unpack('f', b'\xf0\x23\x64\xc9'))
  31. print('ZDR标定温差:', struct.unpack('f', b'\xf0\x23\x64\xc9'))
  32. print('差分组移标定温差:', struct.unpack('f', b'\xf0\x23\x64\xc9'))
  33. print('系统LDR标定温差:', struct.unpack('f', b'\xf0\x23\x64\xc9'))

  34. print('处理方式:', struct.unpack('i', b'\x01\x00\x00\x00'))
  35. print('波形类别:', struct.unpack('i', b'\x00\x00\x00\x00'))
  36. print('脉冲重复频率1:', struct.unpack('f', b'\x00\x00\xaf\x43'))
  37. print('脉冲重复频率2:', struct.unpack('f', b'\x00\x00\x00\x00'))
  38. print('速度退模糊办法:', struct.unpack('i', b'\x01\x00\x00\x00'))
  39. print('方位角:', struct.unpack('f', b'\xf0\x23\x74\xc9'))

  40. print('俯仰角:', struct.unpack('f', b'\x00\x00\x00\x3f'))
  41. print('起始角度:', struct.unpack('f', b'\xf0\x23\x74\xc9'))
  42. print('结束角度:', struct.unpack('f', b'\xf0\x23\x74\xc9'))
  43. print('角度分辨率:', struct.unpack('f', b'\x00\x00\x80\x3f'))
  44. print('扫描速度:', struct.unpack('f', b'\x00\x00\x40\x41'))
  45. print('强度分辨率:', struct.unpack('i', b'\x96\x00\x00\x00'))
  46. print('多普勒分辨率:', struct.unpack('i', b'\x96\x00\x00\x00'))
  47. print('最大距离1:', struct.unpack('i', b'\x1c\x1a\x06\x00'))
  48. print('最大距离2:', struct.unpack('i', b'\x00\x00\x00\x00'))
  49. print('起始距离:', struct.unpack('i', b'\x01\x00\x00\x00'))
  50. print('采样个数1:', struct.unpack('i', b'\x1c\x00\x00\x00'))
  51. print('采样个数2:', struct.unpack('i', b'\x00\x00\x00\x00'))
  52. print('相位编码模式:', struct.unpack('i', b'\x03\x00\x00\x00'))
  53. print('大气衰减:', struct.unpack('f', b'\x6f\x12\x83\x3c'))

  54. print('最大不模糊速度:', struct.unpack('f', b'\x36\xb2\x9a\40'))
  55. print('数据类型掩码:', struct.unpack('q', b'\x06\x00\x01\x00\x00\x00\x00\x00'))
  56. print('数据大小掩码:', struct.unpack('q', b'\x00\x00\x00\x00\x00\x00\x00\x00'))
  57. print('滤波设置掩码:', struct.unpack('i', b'\x00\x00\x00\x80'))
  58. print('SQI门限:', struct.unpack('f', b'\x00\x00\x00\x00'))
  59. print('SIG门限:', struct.unpack('f', b'\x00\x00\xa0\x40'))

  60. print('CSR门限:', struct.unpack('f', b'\x00\x00\x00\x00'))
  61. print('LOG门限:', struct.unpack('f', b'\x00\x00\x80\x3f'))
  62. print('CPA门限:', struct.unpack('f', b'\x00\x00\x00\x00'))
  63. print('PMI门限:', struct.unpack('f', b'\x00\x00\x00\x00'))
  64. print('PMI门限:', struct.unpack('f', b'\x00\x00\x00\x00'))
  65. print('阈值门限保留:', struct.unpack('4s', b'\x00\x00\x00\x00'))
  66. print('dBT质控掩码:', struct.unpack('i', b'\x08\x00\x00\x00'))
  67. print('dBZ质控掩码:', struct.unpack('i', b'\x08\x00\x00\x00'))
  68. print('速度质控掩码:', struct.unpack('i', b'\x08\x00\x00\x00'))
  69. print('谱宽质控掩码:', struct.unpack('i', b'\x08\x00\x00\x00'))
  70. print('偏振量质控掩码:', struct.unpack('i', b'\x00\x00\x00\x80'))

  71. print('扫描标志:', struct.unpack('i', b'\x01\x00\x00\x00'))
  72. print('天线运行方向:', struct.unpack('i', b'\x01\x00\x05\x00'))
  73. print('地物杂波图类型:', struct.unpack('h', b'\x00\x80'))
  74. print('地物滤波类型:', struct.unpack('h', b'\x02\x00'))
  75. print('地物滤波宽度:', struct.unpack('h', b'\x00\x00'))
  76. print('滤波窗口类型:', struct.unpack('h', b'\x00\x00'))
复制代码
结果如下:
  1. 魔术字  : (b'RSTM',)
  2. 主版本号: (2,)
  3. 次版本号: (0,)
  4. 文件类型: (1,)
  5. 产品类型: (128,)
  6. 站号    : (b'Z9871',)
  7. 站名    : (b'KunMing_Z9871',)
  8. 纬度    : (25.051666259765625,)
  9. 经度    : (102.57833099365234,)
  10. 天线高度: (2484,)
  11. 地面高度: (2458,)
  12. 工作频率: (5430.0,)
  13. 水平波束宽度: (1.090000033378601,)
  14. 垂直波束宽度: (1.090000033378601,)
  15. RDA版本号: (131072,)
  16. 雷达类型: (35,)
  17. 任务名称: (b'VCP21',)
  18. 任务描述: (b'SUN CREATE',)
  19. 极化方式: (1,)
  20. 扫描任务类型: (0,)
  21. 脉冲宽度: (1000,)
  22. 扫描开始时间: (1660932693,)
  23. 扫描层数: (11,)
  24. 水平通道噪声: (19.84000015258789,)
  25. 垂直通道噪声: (-999999.0,)
  26. 水平通道标定值: (26.540000915527344,)
  27. 垂直通道标定值: (-999999.0,)
  28. 水平通道噪声温度: (148.16537475585938,)
  29. 垂直通道噪声温度: (-934463.0,)
  30. ZDR标定温差: (-934463.0,)
  31. 差分组移标定温差: (-934463.0,)
  32. 系统LDR标定温差: (-934463.0,)
  33. 处理方式: (1,)
  34. 波形类别: (0,)
  35. 脉冲重复频率1: (350.0,)
  36. 脉冲重复频率2: (0.0,)
  37. 速度退模糊办法: (1,)
  38. 方位角: (-999999.0,)
  39. 俯仰角: (0.5,)
  40. 起始角度: (-999999.0,)
  41. 结束角度: (-999999.0,)
  42. 角度分辨率: (1.0,)
  43. 扫描速度: (12.0,)
  44. 强度分辨率: (150,)
  45. 多普勒分辨率: (150,)
  46. 最大距离1: (399900,)
  47. 最大距离2: (0,)
  48. 起始距离: (1,)
  49. 采样个数1: (28,)
  50. 采样个数2: (0,)
  51. 相位编码模式: (3,)
  52. 大气衰减: (0.01600000075995922,)
  53. 最大不模糊速度: (2.620654488138837e-19,)
  54. 数据类型掩码: (65542,)
  55. 数据大小掩码: (0,)
  56. 滤波设置掩码: (-2147483648,)
  57. SQI门限: (0.0,)
  58. SIG门限: (5.0,)
  59. CSR门限: (0.0,)
  60. LOG门限: (1.0,)
  61. CPA门限: (0.0,)
  62. PMI门限: (0.0,)
  63. PMI门限: (0.0,)
  64. 阈值门限保留: (b'\x00\x00\x00\x00',)
  65. dBT质控掩码: (8,)
  66. dBZ质控掩码: (8,)
  67. 速度质控掩码: (8,)
  68. 谱宽质控掩码: (8,)
  69. 偏振量质控掩码: (-2147483648,)
  70. 扫描标志: (1,)
  71. 天线运行方向: (327681,)
  72. 地物杂波图类型: (-32768,)
  73. 地物滤波类型: (2,)
  74. 地物滤波宽度: (0,)
  75. 滤波窗口类型: (0,)
复制代码
有一些奇怪的数值如 -2147483648,-934463.0 可能是我读错了,明明已经超出了文件格式给定的范围,也有可能是表示“9999”这样意思的数值,如果有老师知道麻烦提示我一下。
下一步我会尝试读取扫描的数据。再弄清楚格式编码之后再尝试输出。


密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2022-11-25 10:24:00 | 显示全部楼层
请问老师读取了反射率了吗
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册 新浪微博登陆

本版积分规则

Copyright ©2011-2014 bbs.06climate.com All Rights Reserved.  Powered by Discuz! (京ICP-10201084)

本站信息均由会员发表,不代表气象家园立场,禁止在本站发表与国家法律相抵触言论

快速回复 返回顶部 返回列表