气ython风雨 发表于 2024-5-15 12:20:12

雷达系列:两个国产雷达Python库读取对比


pycwr与pycinrad读取文件测试
前言
前段时间跟朋友聊了下两个国产雷达库的区别

想了想是不错的素材,遂稍作对比

pycwr和pycinrad都是用于读取和处理气象雷达数据的Python库。
它们的作用是帮助用户方便地读取、处理和分析气象雷达数据,包括反射率、速度和谱宽等信息。
对比这两个库可以让用户更好地了解它们的特点、功能和适用场景,从而更好地选择合适的库来处理气象雷达数据。

SC老格式
In :
from cinrad.io import CinradReader, StandardData
f = CinradReader('/home/mw/input/pycwr5461/Z_RADR_I_Z9240_20190703101340_O_DOR_SC_CAP.bin.bz2') #老版本数据,CC雷达最好加上radar_type
f.available_product(0)
Out:

['REF', 'VEL', 'SW', 'azimuth', 'RF']
In :
VEL = f.get_data(0, 230, 'REF')
VEL

Out:




In :
from pycwr.io import read_auto
PRD = read_auto("/home/mw/input/pycwr5461/Z_RADR_I_Z9240_20190703101340_O_DOR_SC_CAP.bin.bz2")
print(PRD.fields)



SAD标准格式
In :
g = StandardData('/home/mw/input/pycwr5461/Z_RADR_I_Z9898_20190828181529_O_DOR_SAD_CAP_FMT (1).bin.bz2')
g

Out:
<cinrad.io.level2.StandardData at 0x7f7f921358e0>
In :
g.available_product(0)

Out:
['TREF', 'REF', 'SQI', 'ZDR', 'RHO', 'PHI', 'KDP', 'SNRH']
In :
VEL1 = g.get_data(0, 230, 'REF')
VEL1

Out:




In :
PRD = read_auto("/home/mw/input/pycwr5461/Z_RADR_I_Z9898_20190828181529_O_DOR_SAD_CAP_FMT (1).bin.bz2")
print(PRD.fields)


相控阵2020格式
In :
from pycwr.io import read_PA
PRD = read_PA("/home/mw/input/pycwr5461/Z_RADR_I_ZGZ01_20200820220246_O_DOR_DXK_CAR.bin.bz2")
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-43-514a2fb40a87> in <module>
      1 from pycwr.io import read_PA
----> 2 PRD = read_PA("/home/mw/input/pycwr5461/Z_RADR_I_ZGZ01_20200820220246_O_DOR_DXK_CAR.bin.bz2")

/opt/conda/lib/python3.9/site-packages/pycwr/io/__init__.py in read_PA(filename, station_lon, station_lat, station_alt)
   68   :param station_alt:radar station altitude //units: meters
   69   """
---> 70   return PAFile.PA2NRadar(PAFile.PABaseData(filename, station_lon, station_lat, station_alt)).ToPRD()

/opt/conda/lib/python3.9/site-packages/pycwr/io/PAFile.py in __init__(self, filename, station_lon, station_lat, station_alt)
   29         self._check_standard_basedata()##确定文件是standard文件
   30         self.header = self._parse_BaseDataHeader()
---> 31         self.radial = self._parse_radial()
   32         self.nrays = len(self.radial)
   33         # print(self.nrays)

/opt/conda/lib/python3.9/site-packages/pycwr/io/PAFile.py in _parse_radial(self)
   75             self.MomentNum = RadialDict['MomentNumber']
   76             self.LengthOfData = RadialDict['LengthOfData']
---> 77             RadialDict['fields'] = self._parse_radial_single()
   78             if RadialDict["fields"]:
   79               radial.append(RadialDict)

/opt/conda/lib/python3.9/site-packages/pycwr/io/PAFile.py in _parse_radial_single(self)
   87             Momheader, _ = _unpack_from_buf(Mom_buf, 0, dtype_PA.RadialData())
   88             Data_buf = self.fid.read(Momheader['Length'])
---> 89             assert (Momheader['BinLength'] == 1) | (Momheader['BinLength'] == 2), "Bin Length has problem!"
   90             if Momheader['BinLength'] == 1:
   91               dat_tmp = (np.frombuffer(Data_buf, dtype="u1", offset=0)).astype(int)

AssertionError: Bin Length has problem!
In :
from cinrad.io import PhasedArrayData
p = PhasedArrayData('/home/mw/input/pycwr5461/Z_RADR_I_ZGZ01_20200820220246_O_DOR_DXK_CAR.bin.bz2')
data = p.get_data(0, 100, 'REF')
data

---------------------------------------------------------------------------
ValueError                              Traceback (most recent call last)
<ipython-input-42-544a32d2eceb> in <module>
      1 from cinrad.io import PhasedArrayData
----> 2 p = PhasedArrayData('/home/mw/input/pycwr5461/Z_RADR_I_ZGZ01_20200820220246_O_DOR_DXK_CAR.bin.bz2')
      3 data = p.get_data(0, 100, 'REF')
      4 data

/opt/conda/lib/python3.9/site-packages/cinrad/io/level2.py in __init__(self, file)
    884         except IndexError:
    885             self.code = self.name = "None"
--> 886         self._d = data = np.frombuffer(f.read(), dtype=PA_radial)
    887         self.stationlon = data["header"]["longitude"] * 360 / 65535
    888         self.stationlat = data["header"]["latitude"] * 360 / 65535

ValueError: buffer size must be a multiple of element size
为什么都读取错误了呢
这里说明一下,由于相控阵的格式经历了多次改变。
此文件是2020年的相控阵文件,较老版本的pycwr应该是能读取的(因为文件就是来自pycwr的测试文件)
笔者测试过,pycinrad可以读取2022年的标准格式相控阵文件
目前pycwr对标的是2023年的格式。

SB格式
In :
from cinrad.io import CinradReader, StandardData
SB = CinradReader('/home/mw/input/pycwr5461/Z9396_BASE_SB_20180724_055400 (1).bin.bz2',radar_type='SB')
SB.available_product(0)
Out:['REF', 'VEL', 'SW', 'azimuth', 'RF']
In :
VEL = SB.get_data(0, 230, 'REF')
VEL

Out:




In :
from pycwr.io import read_auto
PRD = read_auto("/home/mw/input/pycwr5461/Z9396_BASE_SB_20180724_055400 (1).bin.bz2")
print(PRD.fields)



In :
from cinrad.io import CinradReader, StandardData
CC = CinradReader('/home/mw/input/pycwr5461/Z9396_BASE_SB_20180724_055400 (1).bin.bz2',radar_type='CC')
CC.available_product(0)
---------------------------------------------------------------------------
ValueError                              Traceback (most recent call last)
/opt/conda/lib/python3.9/site-packages/cinrad/io/level2.py in __init__(self, file, radar_type)
    124                     f.seek(0)
--> 125                     self._SAB_reader(f, dtype="special")
    126               except:

/opt/conda/lib/python3.9/site-packages/cinrad/io/level2.py in _SAB_reader(self, f, dtype)
    153             _header_size = 132
--> 154         data = np.frombuffer(f.read(), dtype=radar_dtype)
    155         start = datetime.datetime(1969, 12, 31)

ValueError: buffer size must be a multiple of element size

During handling of the above exception, another exception occurred:

NotImplementedError                     Traceback (most recent call last)
<ipython-input-55-39e883f9ddb5> in <module>
      1 from cinrad.io import CinradReader, StandardData
----> 2 CC = CinradReader('/home/mw/input/pycwr5461/Z9396_BASE_SB_20180724_055400 (1).bin.bz2',radar_type='CC')
      3 CC.available_product(0)

/opt/conda/lib/python3.9/site-packages/cinrad/io/level2.py in __init__(self, file, radar_type)
    125                     self._SAB_reader(f, dtype="special")
    126               except:
--> 127                     raise err
    128         self._update_radar_info()
    129         # TODO: Override information

/opt/conda/lib/python3.9/site-packages/cinrad/io/level2.py in __init__(self, file, radar_type)
    112             try:
    113               if self.radartype == "CC":
--> 114                     self._CC_reader(f)
    115               elif self.radartype in ["SC", "CD"]:
    116                     self._CD_reader(f)

/opt/conda/lib/python3.9/site-packages/cinrad/io/level2.py in _CC_reader(self, f)
    216         scan_mode = header["ucScanMode"]
    217         if scan_mode < 100:
--> 218             raise NotImplementedError("Only VPPI scan mode is supported")
    219         stop_angle = scan_mode - 100
    220         self.scantime = (

NotImplementedError: Only VPPI scan mode is supported
In :
PRD = read_auto("/home/mw/input/pycwr5461/2016070817 (1).48V.gz")
print(PRD.fields)


看来这种扫描模式的CC格式的雷达pycinrad不支持


小结

总的来说,pycwr的read_auto函数比较无脑,很适合萌新
但是pycinrad有官方qq群,有大佬解惑,

pycwr则是毫无交流的地方

对于其他不能读取的雷达格式,那就只能想办法找到说明书去写一个脚本读取了



文章来源于公众号:气python风雨
页: [1]
查看完整版本: 雷达系列:两个国产雷达Python库读取对比