metradar 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. metradar/__init__.py +7 -0
  2. metradar/cnrad_level2.py +1326 -0
  3. metradar/comm_func.py +135 -0
  4. metradar/construct_aws_refvpr_mainprog.py +515 -0
  5. metradar/construct_aws_refvpr_mainprog_cams.py +310 -0
  6. metradar/construct_aws_refvpr_mainprog_datan3d.py +386 -0
  7. metradar/construct_aws_refvpr_mainprog_swan.py +306 -0
  8. metradar/decode_fmt_pyart.py +200 -0
  9. metradar/decode_pup_rose.py +1993 -0
  10. metradar/draw_mosaic_new.py +421 -0
  11. metradar/draw_radar_aws_jilin_new.py +206 -0
  12. metradar/draw_radar_comp_func.py +1379 -0
  13. metradar/exceptions.py +50 -0
  14. metradar/geo_transforms_pyart.py +627 -0
  15. metradar/get_cross_section_from_pyart.py +354 -0
  16. metradar/get_tlogp_from_sharppy.py +93 -0
  17. metradar/grid.py +281 -0
  18. metradar/grid_data.py +64 -0
  19. metradar/main_pydda.py +653 -0
  20. metradar/make_gif.py +24 -0
  21. metradar/make_mosaic_mp_archive.py +538 -0
  22. metradar/mosaic_merge.py +64 -0
  23. metradar/mosaic_quickdraw.py +338 -0
  24. metradar/nowcast_by_pysteps.py +219 -0
  25. metradar/oa_couhua.py +166 -0
  26. metradar/oa_dig_func.py +955 -0
  27. metradar/parse_pal.py +148 -0
  28. metradar/pgmb_io.py +169 -0
  29. metradar/prepare_for_radar_draw.py +197 -0
  30. metradar/read_new_mosaic.py +33 -0
  31. metradar/read_new_mosaic_func.py +231 -0
  32. metradar/retrieve_cmadaas.py +3126 -0
  33. metradar/retrieve_micaps_server.py +2061 -0
  34. metradar/rose_structer.py +807 -0
  35. metradar/trans_nc_pgmb.py +62 -0
  36. metradar/trans_new_mosaic_nc.py +309 -0
  37. metradar/trans_polor2grid_func.py +203 -0
  38. metradar-0.1.0.dist-info/METADATA +12 -0
  39. metradar-0.1.0.dist-info/RECORD +41 -0
  40. metradar-0.1.0.dist-info/WHEEL +5 -0
  41. metradar-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,354 @@
1
+ '''
2
+ 从pyart的radar object中获取任意垂直剖面的数据
3
+
4
+ 朱文剑
5
+ 2021.10.14
6
+
7
+ '''
8
+
9
+ import numpy as np
10
+ from pyart.core import Radar
11
+ import math
12
+ # import time
13
+
14
+ R = 6371 # km
15
+ #该程序用来求直线方程系数
16
+ #目前没考虑垂直X轴的直线,需要完善
17
+ #kevin2075@163.com
18
+ def linefunc(x,y,x1,y1): #直接输入两个坐标就可以求出一条直线方程。
19
+ # if x~=x1
20
+ a=(y1-y)/(x1-x)
21
+ b=y-a*x
22
+ return [a,b]
23
+
24
+
25
+ # 将多个数或列表组合成一个列表
26
+ def myconcat(vars:tuple):
27
+ result=[]
28
+ for vartmp in vars:
29
+ if len(np.array(vartmp).shape)==0:
30
+ result.append(vartmp)
31
+ else:
32
+ for var in vartmp:
33
+ result.append(var)
34
+
35
+ return result
36
+
37
+ def get_cross_radar(radar:Radar,params):
38
+
39
+ # antenna_to_cartesian(147, 260, 1.5)
40
+ # startangle=None,startrange=None,endangle=None,endrange=None
41
+ # startangle = 8.5
42
+ # startrange = 69.23 #km
43
+
44
+ # endangle = 18.6;
45
+ # endrange = 59.03 #km
46
+ startangle = params['crs_start_azi']
47
+ startrange = params['crs_start_range']
48
+ endangle = params['crs_end_azi']
49
+ endrange = params['crs_end_range']
50
+ toph = params['top_height']
51
+
52
+ startx = startrange*np.sin(np.radians(startangle))
53
+ starty = startrange*np.cos(np.radians(startangle))
54
+ endx = endrange*np.sin(np.radians(endangle))
55
+ endy = endrange*np.cos(np.radians(endangle))
56
+
57
+ baseh = 0; # km 垂直剖面的起始高度
58
+ # toph = 20; # km 垂直剖面的上限高度
59
+
60
+ validzlv=[]
61
+ validvlv=[]
62
+ validReles=[]
63
+ validDeles=[]
64
+ outdic=dict()
65
+
66
+ for il in range(radar.nsweeps):
67
+ # if sweep(il).RGates > 0
68
+ # if il !=1 and il !=3:
69
+ # validzlv.append(il)
70
+ # validReles.append(radar.get_elevation(il).mean())
71
+ # if il !=0 and il !=2:
72
+ # validvlv.append(il)
73
+ # validDeles.append(radar.get_elevation(il).mean())
74
+ validzlv.append(il)
75
+ validReles.append(round(radar.get_elevation(il).mean(),1))
76
+ validvlv.append(il)
77
+ validDeles.append(round(radar.get_elevation(il).mean(),1))
78
+
79
+ tol_length = int(np.sqrt(np.power((endx-startx),2) + np.power((endy - starty),2)))
80
+
81
+ #求方程坐标,这里暂时没考虑X=0的情况,后面要完善这一点
82
+ [a,b] = linefunc(startx,starty,endx,endy)
83
+
84
+ # 获取反射率垂直剖面
85
+
86
+ #构建变量,确定坐标维度
87
+ xreso = 0.05#km
88
+ if endx < startx:
89
+ xreso = -1*xreso
90
+
91
+ xnum = int(tol_length / abs(xreso))
92
+ zreso = 0.05# km
93
+ znum = int((toph - baseh) / zreso)
94
+
95
+
96
+
97
+ beamwidth = radar.get_azimuth(validzlv[-1])
98
+ beamwidth = np.diff(beamwidth)
99
+ beamwidth = np.mean(beamwidth[beamwidth>0])
100
+ topel_R = max(validReles) + beamwidth / 2
101
+ baseel_R = min(validReles) - beamwidth / 2
102
+
103
+ topel_D = max(validDeles) + beamwidth / 2
104
+ baseel_D = min(validDeles) - beamwidth / 2
105
+
106
+ tmp=[]
107
+ for nn in range(len(validReles)-1):
108
+ tmp.append(np.mean([validReles[nn],validReles[nn+1]]))
109
+
110
+ tmp_newRel = sorted(myconcat((tmp,validReles)))
111
+
112
+ tmp=[]
113
+ for nn in range(len(validDeles)-1):
114
+ tmp.append(np.mean([validDeles[nn],validDeles[nn+1]]))
115
+
116
+ tmp_newDel = sorted(tmp+validDeles)
117
+
118
+ newRel = [baseel_R+tmp_newRel+topel_R]
119
+ newDel = [baseel_D+tmp_newDel+topel_D]
120
+
121
+ # for varkey in radar.fields.keys():
122
+
123
+ nflag=0
124
+ outdic=dict()
125
+ outdic['vertical_km'] = toph - baseh
126
+ outdic['horizontal_km'] = tol_length
127
+ outdic['xreso'] = xreso
128
+ outdic['yreso'] = zreso
129
+
130
+ for varkey in radar.fields.keys():
131
+ outdic[varkey]=[]
132
+ outdic[varkey] = np.zeros([znum,xnum],dtype='float')*np.nan
133
+
134
+
135
+ # 纯 for 循环版本 =====================
136
+ valideles=[]
137
+ validlvl=[]
138
+ for varkey in radar.fields.keys():
139
+ print(varkey)
140
+ if varkey == 'reflectivity' :
141
+ valideles = validReles
142
+ validlvl = validzlv
143
+ elif varkey == 'velocity':
144
+ valideles = validDeles
145
+ validlvl = validvlv
146
+ else:
147
+ # print('暂时仅支持回波强度和径向速度')
148
+ continue
149
+
150
+ curfd = []
151
+ for il in range(radar.nsweeps):
152
+ curfd.append(radar.get_field(il,varkey))#sweep(targetsp).dbz(az,gates);
153
+
154
+ for iz in range(znum):
155
+ for ix in range(xnum):
156
+ tmpcurx = startx + (ix * xreso) * math.cos(math.atan(a))
157
+
158
+ tmpcury = a * tmpcurx + b
159
+ tmpaz = (90 - math.degrees(math.atan2(tmpcury,tmpcurx)) + 360)%360
160
+
161
+ curx = math.sqrt(math.pow(tmpcurx,2) + math.pow(tmpcury,2))#startrange + xreso * ix
162
+ curz = baseh + iz * zreso
163
+
164
+ #计算相对雷达的仰角
165
+ # ele = math.degrees(math.atan2(curz,curx))
166
+ # 这里必须用math.pow,如果直接用称号会有较大误差
167
+ ele = math.asin((math.pow((curz+R),2) - math.pow(curx,2) - math.pow(R,2))/2/curx/R)/np.pi*180
168
+
169
+ if ele < baseel_R or ele > topel_R:
170
+ continue
171
+
172
+ tmp = list(abs(np.array(valideles) - ele))
173
+ idx = tmp.index(min(tmp))
174
+ idx_el = idx
175
+
176
+ targetsp = validlvl[idx_el]
177
+
178
+ #获取方位角角标
179
+ tmp = list(abs(radar.get_azimuth(targetsp) - tmpaz))
180
+ idx = tmp.index(min(tmp))
181
+ az = idx
182
+
183
+ #经向距离,由该页面的公式进行反算
184
+ #https://arm-doe.github.io/pyart/API/generated/pyart.core.antenna_to_cartesian.html#pyart.core.antenna_to_cartesian
185
+ #根据s=R*??的公式反算r
186
+
187
+ cur_range = (R+curz)*math.sin(curx/R)/math.cos(math.radians(valideles[idx_el]))
188
+ gates = math.floor(cur_range/(radar.range['meters_between_gates'] / 1000)+0.5)-1
189
+ # gates = math.floor(curx/math.cos(math.radians(valideles[idx_el]))/(radar.range['meters_between_gates'] / 1000)+0.5)-1
190
+
191
+ if gates < radar.ngates:
192
+ #disp(sweep(targetsp).dbz(az,gates));
193
+ # if curfd[targetsp].data[az,gates] > -30 and not curfd[targetsp].mask[az,gates]:
194
+ # if curfd[targetsp].data[az,gates] > -5:
195
+ if not curfd[targetsp].mask[az,gates]:
196
+ outdic[varkey][iz,ix] = curfd[targetsp].data[az,gates]
197
+ nflag+=1
198
+
199
+ return outdic
200
+
201
+ # main function
202
+ def get_cross_radar_old(radar:Radar,params):
203
+ # startangle=None,startrange=None,endangle=None,endrange=None
204
+ # startangle = 8.5
205
+ # startrange = 69.23 #km
206
+
207
+ # endangle = 18.6;
208
+ # endrange = 59.03 #km
209
+ startangle = params['crs_start_azi']
210
+ startrange = params['crs_start_range']
211
+ endangle = params['crs_end_azi']
212
+ endrange = params['crs_end_range']
213
+ toph = params['top_height']
214
+
215
+ startx = startrange*np.sin(np.radians(startangle))
216
+ starty = startrange*np.cos(np.radians(startangle))
217
+ endx = endrange*np.sin(np.radians(endangle))
218
+ endy = endrange*np.cos(np.radians(endangle))
219
+
220
+ baseh = 0; # km 垂直剖面的起始高度
221
+ # toph = 20; # km 垂直剖面的上限高度
222
+
223
+ validzlv=[]
224
+ validvlv=[]
225
+ validReles=[]
226
+ validDeles=[]
227
+ outdic=dict()
228
+
229
+ for il in range(radar.nsweeps):
230
+ # if sweep(il).RGates > 0
231
+ # if il !=1 and il !=3:
232
+ # validzlv.append(il)
233
+ # validReles.append(radar.get_elevation(il).mean())
234
+ # if il !=0 and il !=2:
235
+ # validvlv.append(il)
236
+ # validDeles.append(radar.get_elevation(il).mean())
237
+ validzlv.append(il)
238
+ validReles.append(round(radar.get_elevation(il).mean(),1))
239
+ validvlv.append(il)
240
+ validDeles.append(round(radar.get_elevation(il).mean(),1))
241
+
242
+ tol_length = np.sqrt(np.power((endx-startx),2) + np.power((endy - starty),2))
243
+
244
+ #求方程坐标,这里暂时没考虑X=0的情况,后面要完善这一点
245
+ [a,b] = linefunc(startx,starty,endx,endy)
246
+
247
+ # 获取反射率垂直剖面
248
+
249
+ #构建变量,确定坐标维度
250
+ xreso = 0.25#km
251
+ if endx < startx:
252
+ xreso = -1*xreso
253
+
254
+ xnum = int(tol_length / abs(xreso))
255
+ yreso = 0.25# km
256
+ ynum = int((toph - baseh) / yreso)
257
+
258
+
259
+
260
+ beamwidth = radar.get_azimuth(validzlv[-1])
261
+ beamwidth = np.diff(beamwidth)
262
+ beamwidth = np.mean(beamwidth[beamwidth>0])
263
+ topel_R = max(validReles) + beamwidth / 2
264
+ baseel_R = min(validReles) - beamwidth / 2
265
+
266
+ topel_D = max(validDeles) + beamwidth / 2
267
+ baseel_D = min(validDeles) - beamwidth / 2
268
+
269
+ tmp=[]
270
+ for nn in range(len(validReles)-1):
271
+ tmp.append(np.mean([validReles[nn],validReles[nn+1]]))
272
+
273
+ tmp_newRel = sorted(myconcat((tmp,validReles)))
274
+
275
+ tmp=[]
276
+ for nn in range(len(validDeles)-1):
277
+ tmp.append(np.mean([validDeles[nn],validDeles[nn+1]]))
278
+
279
+ tmp_newDel = sorted(tmp+validDeles)
280
+
281
+ newRel = [baseel_R+tmp_newRel+topel_R]
282
+ newDel = [baseel_D+tmp_newDel+topel_D]
283
+
284
+ # for varkey in radar.fields.keys():
285
+
286
+ nflag=0
287
+ outdic=dict()
288
+ outdic['vertical_km'] = toph - baseh
289
+ outdic['horizontal_km'] = tol_length
290
+ outdic['xreso'] = xreso
291
+ outdic['yreso'] = yreso
292
+
293
+ for varkey in radar.fields.keys():
294
+ outdic[varkey]=[]
295
+ outdic[varkey] = np.zeros([ynum,xnum],dtype='float')*np.nan
296
+
297
+
298
+ # 纯 for 循环版本 =====================
299
+ valideles=[]
300
+ validlvl=[]
301
+ for varkey in radar.fields.keys():
302
+ print(varkey)
303
+ if varkey == 'reflectivity' :
304
+ valideles = validReles
305
+ validlvl = validzlv
306
+ elif varkey == 'velocity':
307
+ valideles = validDeles
308
+ validlvl = validvlv
309
+ else:
310
+ # print('暂时仅支持回波强度和径向速度')
311
+ continue
312
+
313
+ curfd = []
314
+ for il in range(radar.nsweeps):
315
+ curfd.append(radar.get_field(il,varkey))#sweep(targetsp).dbz(az,gates);
316
+
317
+ for iy in range(ynum):
318
+ for ix in range(xnum):
319
+ tmpcurx = startx + (ix * xreso) * math.cos(math.atan(a))
320
+
321
+ tmpcury = a * tmpcurx + b
322
+ tmpaz = (90 - math.degrees(math.atan2(tmpcury,tmpcurx)) + 360)%360
323
+
324
+ curx = math.sqrt(math.pow(tmpcurx,2) + math.pow(tmpcury,2))#startrange + xreso * ix
325
+ cury = baseh + iy * yreso
326
+
327
+ #计算相对雷达的仰角
328
+ ele = math.degrees(math.atan2(cury,curx))
329
+ # if ele < baseel_R: ele = baseel_R
330
+ # if ele > topel_R: continue
331
+ if ele < baseel_R or ele > topel_R:
332
+ continue
333
+
334
+ tmp = list(abs(np.array(valideles) - ele))
335
+ idx = tmp.index(min(tmp))
336
+ idx_el = idx
337
+
338
+ targetsp = validlvl[idx_el]
339
+
340
+ #获取方位角角标
341
+ tmp = list(abs(radar.get_azimuth(targetsp) - tmpaz))
342
+ idx = tmp.index(min(tmp))
343
+ az = idx
344
+
345
+ gates = math.ceil(curx/math.cos(math.radians(valideles[idx_el]))/(radar.range['meters_between_gates'] / 1000))
346
+
347
+ if gates < radar.ngates:
348
+ #disp(sweep(targetsp).dbz(az,gates));
349
+ if curfd[targetsp].data[az,gates] > -30:
350
+ outdic[varkey][iy,ix] = curfd[targetsp].data[az,gates]
351
+ nflag+=1
352
+
353
+ return outdic
354
+
@@ -0,0 +1,93 @@
1
+ '''
2
+ 从sharppy格式的探空数据中获取风廓线,作为背景场
3
+ 2021.3.9
4
+ 朱文剑
5
+ '''
6
+
7
+ # %%
8
+ import os
9
+ import re
10
+ import numpy as np
11
+ from pyart.core.wind_profile import HorizontalWindProfile
12
+ import warnings
13
+ warnings.filterwarnings("ignore")
14
+
15
+ def get_profile(filepath,filename):
16
+ # filepath = '/Users/wenjianzhu/Downloads/CMADAAS/tlogp'
17
+ # filename = '20061208.58238'
18
+
19
+ fin = open(filepath + os.sep + filename,'rt')
20
+
21
+ nflag_title=0
22
+ nflag_raw=0
23
+ nflag=0
24
+ profile=dict()
25
+ defaultvalue = '99999'
26
+ for line in fin.readlines():
27
+ # print(line)
28
+ nflag = nflag + 1
29
+ if line.find('%TITLE%') >=0 :
30
+ nflag_title = nflag
31
+ if line.find('%RAW%') >=0 :
32
+ nflag_raw = nflag
33
+
34
+ # 遇到文档结束
35
+ if line.find('%END%') >=0 :
36
+ break
37
+ #获取站号,时间信息
38
+ if nflag == nflag_title + 1:
39
+ profile['staname'] = line.split(' ')[0]
40
+
41
+ #获取经纬度信息
42
+ if nflag == nflag_title + 2:
43
+ tmp = re.findall(r"\d+\.?\d*",line)
44
+ if len(tmp) == 2:
45
+ profile['lon'] = tmp[0]
46
+ profile['lat'] = tmp[1]
47
+ else:
48
+ profile['lon'] = defaultvalue
49
+ profile['lat'] = defaultvalue
50
+
51
+ #获取变量名称
52
+ if nflag == nflag_title + 3:
53
+ tmp = line.split(' ')
54
+ varnames = [i.strip('\n') for i in tmp if i != '']
55
+ # print(varnames)
56
+ if len(varnames) ==6:
57
+ for dd in range(len(varnames)):
58
+ profile[varnames[dd]]=[]
59
+ # exec('{} = []'.format(varnames[dd]))
60
+ else:
61
+ print('变量个数不够,请检查')
62
+ break
63
+
64
+ # 数据
65
+ if nflag > nflag_raw:
66
+ tmp = re.findall(r"\d+\.?\d*",line)
67
+ if len(tmp) ==6:
68
+ values = np.fromstring( line, sep=',')
69
+ value_str = [str(value) for value in values]
70
+ for dd in range(len(value_str)):
71
+ # exec('{}.append({})'.format(varnames[dd], value_str[dd]))
72
+ profile[varnames[dd]].append(values[dd])
73
+ else:
74
+ continue
75
+ # for dd in range(len(varnames)):
76
+ # exec("profile.update({'%s':%s})"%(varnames[dd],varnames[dd]))
77
+
78
+ outprofile = HorizontalWindProfile(
79
+ profile['HGHT'], np.array(profile['WSPD'])/1.94, profile['WDIR'], latitude=np.tile(float(profile['lat']), len(profile['HGHT'])), longitude=np.tile(float(profile['lon']), len(profile['HGHT'])))
80
+
81
+ fin.close()
82
+ print('profile read over!')
83
+ return outprofile
84
+
85
+ if __name__ == '__main__':
86
+ filepath = 'tlogp'
87
+ filename = '22060608.59280'
88
+ profile = get_profile(filepath,filename)
89
+ pass
90
+
91
+
92
+
93
+ # %%