metradar 0.1.5__py3-none-any.whl → 0.1.8__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.
- metradar/__init__.py +4 -2
- metradar/config.py +53 -0
- metradar/core/__init__.py +9 -0
- metradar/{get_cross_section_from_pyart.py → core/get_cross_section.py} +5 -157
- metradar/{mosaic_merge.py → core/mosaic_merge.py} +3 -1
- metradar/{oa_dig_func.py → core/oa_dig_func.py} +83 -333
- metradar/graph/__init__.py +9 -0
- metradar/{mosaic_quickdraw.py → graph/draw_comp_mosaic.py} +71 -68
- metradar/{draw_mosaic_new.py → graph/draw_latlon_func.py} +177 -173
- metradar/graph/draw_radar_aws.py +212 -0
- metradar/{draw_radar_comp_func.py → graph/draw_radar_comp_func.py} +319 -248
- metradar/graph/parse_pal.py +157 -0
- metradar/io/__init__.py +9 -0
- metradar/{cnrad_level2.py → io/cnrad_level2.py} +45 -2
- metradar/{decode_fmt_pyart.py → io/decode_fmt_pyart.py} +19 -3
- metradar/{decode_pup_rose.py → io/decode_pup_rose.py} +241 -684
- metradar/{read_new_mosaic_func.py → io/read_new_mosaic_func.py} +30 -2
- metradar/io/read_swan.py +250 -0
- metradar/{rose_structer.py → io/rose_structer.py} +2 -0
- metradar/project/__init__.py +9 -0
- metradar/project/make_mosaic/__init__.py +9 -0
- metradar/project/make_mosaic/batch_draw_mosaic.py +32 -0
- metradar/{make_mosaic_mp_archive.py → project/make_mosaic/make_mosaic_func.py} +144 -175
- metradar/project/make_mosaic/make_mosaic_mp.ini +29 -0
- metradar/project/make_mosaic/make_mosaic_mp.py +70 -0
- metradar/project/make_vpr_aws/__init__.py +9 -0
- metradar/project/make_vpr_aws/construct_aws_refvpr_mainprog.ini +39 -0
- metradar/project/make_vpr_aws/construct_aws_refvpr_mainprog.py +565 -0
- metradar/project/nowcasting/__init__.py +9 -0
- metradar/project/nowcasting/nowcast_by_pysteps.py +214 -0
- metradar/{trans_nc_pgmb.py → project/nowcasting/trans_mosaic_pgmb.py} +19 -17
- metradar/project/qpe/Archive /346/250/241/345/274/217/350/257/264/346/230/216.txt" +2 -0
- metradar/project/qpe/__init__.py +9 -0
- metradar/project/qpe/archive_main_qpe_cfg.ini +91 -0
- metradar/project/qpe/do_s1.sh +6 -0
- metradar/project/qpe/do_s2.sh +6 -0
- metradar/project/qpe/do_s3.sh +6 -0
- metradar/project/qpe/do_s4.sh +6 -0
- metradar/project/qpe/do_s5.sh +6 -0
- metradar/project/qpe/exec_all.sh +11 -0
- metradar/project/qpe/get_rainrate_func.py +80 -0
- metradar/project/qpe/main_qpe_cfg.ini +85 -0
- metradar/project/qpe/s1_download_radar_region_cmadaas.py +123 -0
- metradar/project/qpe/s2_pre_process_single_radar.py +183 -0
- metradar/project/qpe/s3_trans_rainrate_to_qpe.py +499 -0
- metradar/project/qpe/s4_mosaic_qpe.py +523 -0
- metradar/project/qpe/s5_draw_qpe_mosaic.py +308 -0
- metradar/project/wind_retrieval/__init__.py +9 -0
- metradar/project/wind_retrieval/config_3dwind.ini +45 -0
- metradar/{main_pydda.py → project/wind_retrieval/main_pydda.py} +152 -149
- metradar/util/__init__.py +9 -0
- metradar/{comm_func.py → util/comm_func.py} +1 -41
- metradar/util/exceptions.py +50 -0
- metradar/util/geo_transforms_pyart.py +627 -0
- metradar/{get_tlogp_from_sharppy.py → util/get_tlogp_from_sharppy.py} +16 -5
- metradar/{parse_pal.py → util/parse_pal.py} +147 -147
- metradar/util/radar_common.py +16 -0
- metradar/{trans_new_mosaic_nc.py → util/trans_new_mosaic_nc.py} +1 -1
- metradar-0.1.8.dist-info/METADATA +91 -0
- metradar-0.1.8.dist-info/RECORD +67 -0
- {metradar-0.1.5.dist-info → metradar-0.1.8.dist-info}/WHEEL +1 -1
- metradar-0.1.8.dist-info/licenses/LICENSE +21 -0
- metradar/grid.py +0 -281
- metradar/grid_data.py +0 -64
- metradar/oa_couhua.py +0 -166
- metradar/read_new_mosaic.py +0 -33
- metradar/retrieve_cmadaas.py +0 -3126
- metradar/retrieve_micaps_server.py +0 -2061
- metradar-0.1.5.dist-info/METADATA +0 -37
- metradar-0.1.5.dist-info/RECORD +0 -33
- /metradar/{pgmb_io.py → io/pgmb_io.py} +0 -0
- /metradar/{exceptions.py → project/make_vpr_aws/exceptions.py} +0 -0
- /metradar/{geo_transforms_pyart.py → project/make_vpr_aws/geo_transforms_pyart.py} +0 -0
- /metradar/{make_gif.py → util/make_gif.py} +0 -0
- {metradar-0.1.5.dist-info → metradar-0.1.8.dist-info}/top_level.txt +0 -0
|
@@ -1,24 +1,28 @@
|
|
|
1
|
+
# _*_ coding: utf-8 _*_
|
|
2
|
+
|
|
1
3
|
'''
|
|
2
4
|
自动站资料客观分析程序
|
|
3
5
|
朱文剑
|
|
4
|
-
|
|
6
|
+
|
|
5
7
|
'''
|
|
6
8
|
|
|
7
9
|
# %%
|
|
8
|
-
|
|
10
|
+
from metpy.interpolate import interpolate_to_grid
|
|
11
|
+
import nmc_met_io.retrieve_micaps_server as mserver
|
|
9
12
|
import pandas as pd
|
|
10
13
|
import matplotlib.pyplot as plt
|
|
11
14
|
import xarray as xr
|
|
12
15
|
import numpy as np
|
|
13
16
|
from collections import OrderedDict
|
|
14
|
-
|
|
17
|
+
from metpy.units import units
|
|
18
|
+
from metpy.calc import wind_components,vorticity,divergence,lat_lon_grid_deltas
|
|
15
19
|
import os
|
|
16
20
|
import gc
|
|
17
21
|
from datetime import datetime,timedelta
|
|
18
|
-
from oa_couhua import interp_sg_oa
|
|
19
22
|
import matplotlib
|
|
20
23
|
matplotlib.use('Agg')
|
|
21
24
|
|
|
25
|
+
|
|
22
26
|
def remove_nan_observations(x, y, z):
|
|
23
27
|
r"""Remove all x, y, and z where z is nan.
|
|
24
28
|
|
|
@@ -96,62 +100,6 @@ def get_contour_verts(cn):
|
|
|
96
100
|
|
|
97
101
|
return contours
|
|
98
102
|
|
|
99
|
-
# 从色标文件中获取色标数据
|
|
100
|
-
def get_colordf_from_file(colorfile='NCV_bright.rgb',reverse=False):
|
|
101
|
-
filepath = 'colors_ncl'
|
|
102
|
-
|
|
103
|
-
# filename = 'NCV_bright.rgb'
|
|
104
|
-
if not os.path.exists(filepath + os.sep + colorfile):
|
|
105
|
-
print(filepath + os.sep + colorfile + ' not exists!')
|
|
106
|
-
return None
|
|
107
|
-
|
|
108
|
-
try:
|
|
109
|
-
fin = open(filepath + os.sep + colorfile,'rt')
|
|
110
|
-
line=' '
|
|
111
|
-
line = fin.readline()
|
|
112
|
-
line = fin.readline()
|
|
113
|
-
r=[]
|
|
114
|
-
g=[]
|
|
115
|
-
b=[]
|
|
116
|
-
while True:
|
|
117
|
-
line = fin.readline()
|
|
118
|
-
if line == '':
|
|
119
|
-
break
|
|
120
|
-
tmp =line.split(' ')
|
|
121
|
-
|
|
122
|
-
while '' in tmp:
|
|
123
|
-
tmp.remove('')
|
|
124
|
-
# print(tmp)
|
|
125
|
-
r.append(int(tmp[0]))
|
|
126
|
-
g.append(int(tmp[1]))
|
|
127
|
-
b.append(int(tmp[2]))
|
|
128
|
-
if reverse:
|
|
129
|
-
r = np.flipud(r)
|
|
130
|
-
g = np.flipud(g)
|
|
131
|
-
b = np.flipud(b)
|
|
132
|
-
df = pd.DataFrame({'r':r,'g':g,'b':b})
|
|
133
|
-
fin.close()
|
|
134
|
-
return df
|
|
135
|
-
except:
|
|
136
|
-
return None
|
|
137
|
-
|
|
138
|
-
colors_gr2=[
|
|
139
|
-
[180, 215, 158],
|
|
140
|
-
[180, 180, 255],
|
|
141
|
-
[120, 120, 255],
|
|
142
|
-
[74, 199, 255],
|
|
143
|
-
[ 0, 180, 180],
|
|
144
|
-
[ 0, 255, 255],
|
|
145
|
-
[ 0, 255, 0],
|
|
146
|
-
[255, 255, 0],
|
|
147
|
-
[255, 128, 0],
|
|
148
|
-
[255, 0, 0],
|
|
149
|
-
[160, 0, 0],
|
|
150
|
-
[255, 0, 255],
|
|
151
|
-
[128, 0, 128],
|
|
152
|
-
[255, 255, 255]
|
|
153
|
-
]
|
|
154
|
-
|
|
155
103
|
# 客观分析类
|
|
156
104
|
# 参考metpy等诊断分析库
|
|
157
105
|
class Object_Analyst:
|
|
@@ -257,7 +205,7 @@ class Object_Analyst:
|
|
|
257
205
|
params['out_long_name'] = 'surface temperature objective analyse'
|
|
258
206
|
params['out_short_name'] = 'oa_t'
|
|
259
207
|
params['out_units'] = 'degC'
|
|
260
|
-
|
|
208
|
+
|
|
261
209
|
params['tipname'] = '温度'
|
|
262
210
|
outdata = self.do_oa_base(params)
|
|
263
211
|
|
|
@@ -275,7 +223,7 @@ class Object_Analyst:
|
|
|
275
223
|
params['out_long_name'] = 'surface dewpoint temperature objective analyse'
|
|
276
224
|
params['out_short_name'] = 'oa_td'
|
|
277
225
|
params['out_units'] = 'degC'
|
|
278
|
-
|
|
226
|
+
|
|
279
227
|
params['tipname'] = '露点温度'
|
|
280
228
|
outdata = self.do_oa_base(params)
|
|
281
229
|
|
|
@@ -293,7 +241,7 @@ class Object_Analyst:
|
|
|
293
241
|
params['out_long_name'] = 'surface relative humidility objective analyse'
|
|
294
242
|
params['out_short_name'] = 'oa_rh'
|
|
295
243
|
params['out_units'] = '%'
|
|
296
|
-
|
|
244
|
+
|
|
297
245
|
params['tipname'] = '相对湿度'
|
|
298
246
|
outdata = self.do_oa_base(params)
|
|
299
247
|
|
|
@@ -311,7 +259,7 @@ class Object_Analyst:
|
|
|
311
259
|
params['out_long_name'] = 'sea pressure objective analyse'
|
|
312
260
|
params['out_short_name'] = 'oa_sprs'
|
|
313
261
|
params['out_units'] = 'hPa'
|
|
314
|
-
|
|
262
|
+
|
|
315
263
|
params['tipname'] = '海平面气压'
|
|
316
264
|
outdata = self.do_oa_base(params)
|
|
317
265
|
|
|
@@ -394,51 +342,42 @@ class Object_Analyst:
|
|
|
394
342
|
params['out_long_name'] = 'surface temperature objective analyse'
|
|
395
343
|
params['out_short_name'] = 'oa_t'
|
|
396
344
|
params['out_units'] = 'degC'
|
|
397
|
-
params['method'] = 'couhua'
|
|
398
345
|
outdata = self.do_oa_base(params)
|
|
399
346
|
elif vartype.find('露点')>=0:
|
|
400
347
|
params['out_varname'] = 'td2m'
|
|
401
348
|
params['out_long_name'] = 'surface dewpoint temperature objective analyse'
|
|
402
349
|
params['out_short_name'] = 'oa_td'
|
|
403
|
-
params['out_units'] = 'degC'
|
|
404
|
-
params['method'] = 'couhua'
|
|
350
|
+
params['out_units'] = 'degC'
|
|
405
351
|
outdata = self.do_oa_base(params)
|
|
406
352
|
elif vartype.find('湿度')>=0:
|
|
407
353
|
params['out_varname'] = 'rh2m'
|
|
408
354
|
params['out_long_name'] = 'surface relative humidility objective analyse'
|
|
409
355
|
params['out_short_name'] = 'oa_rh'
|
|
410
356
|
params['out_units'] = '%'
|
|
411
|
-
params['method'] = 'couhua'
|
|
412
357
|
outdata = self.do_oa_base(params)
|
|
413
358
|
elif vartype.find('气压')>=0:
|
|
414
359
|
params['out_varname'] = 'sprs2m'
|
|
415
360
|
params['out_long_name'] = 'sea pressure objective analyse'
|
|
416
361
|
params['out_short_name'] = 'oa_sprs'
|
|
417
362
|
params['out_units'] = 'hPa'
|
|
418
|
-
params['method'] = 'couhua'
|
|
419
363
|
outdata = self.do_oa_base(params)
|
|
420
364
|
elif vartype.find('变温')>=0:
|
|
421
365
|
params['out_varname'] = 't2m_delta_' + varname.split('_')[-1]
|
|
422
366
|
params['out_long_name'] = 'surface temperature delta objective analyse'
|
|
423
367
|
params['out_short_name'] = 'oa_t_delta' + varname.split('_')[-1]
|
|
424
368
|
params['out_units'] = 'degC'
|
|
425
|
-
params['method'] = 'couhua'
|
|
426
369
|
outdata = self.do_oa_base(params)
|
|
427
370
|
elif vartype.find('变压')>=0:
|
|
428
371
|
params['out_varname'] = 'sprs2m_delta_' + varname.split('_')[-1]
|
|
429
372
|
params['out_long_name'] = 'sea pressure delta objective analyse'
|
|
430
373
|
params['out_short_name'] = 'oa_sprs_delta' + varname.split('_')[-1]
|
|
431
374
|
params['out_units'] = 'hPa'
|
|
432
|
-
params['method'] = 'couhua'
|
|
433
375
|
outdata = self.do_oa_base(params)
|
|
434
376
|
return outdata
|
|
435
377
|
|
|
436
378
|
# 进行客观分析的基础函数
|
|
437
379
|
def do_oa_base(self,params):
|
|
438
|
-
|
|
439
|
-
if not 'method' in params.keys():
|
|
440
|
-
print('key "method" should be set')
|
|
441
|
-
return False
|
|
380
|
+
|
|
442
381
|
|
|
443
382
|
if not 'in_lon' in params.keys():
|
|
444
383
|
print('key "in_lon" should be set')
|
|
@@ -498,17 +437,12 @@ class Object_Analyst:
|
|
|
498
437
|
# self.set_reso(0.05)
|
|
499
438
|
# 温度插值
|
|
500
439
|
# hreso = 0.05
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
else:
|
|
508
|
-
# 用凑华的oa方法
|
|
509
|
-
# gx, gy, gd = interp_sg_oa(lonlist, latlist, data,hreso)
|
|
510
|
-
gx, gy, gd = interp_sg_oa(x_masked, y_masked, data,self.reso,[self.minlon,self.maxlon,self.minlat,self.maxlat],sm=20)
|
|
511
|
-
pass
|
|
440
|
+
|
|
441
|
+
gx, gy, gd = interpolate_to_grid(x_masked, y_masked, data,
|
|
442
|
+
interp_type='cressman',hres=self.reso,
|
|
443
|
+
minimum_neighbors=1,
|
|
444
|
+
)
|
|
445
|
+
|
|
512
446
|
|
|
513
447
|
# 将客观分析结果在x和y方向调整坐标
|
|
514
448
|
gd = gd.T
|
|
@@ -582,7 +516,7 @@ class Object_Analyst:
|
|
|
582
516
|
params['out_long_name'] = 'surface temperature objective analyse'
|
|
583
517
|
params['out_short_name'] = 'oa_t'
|
|
584
518
|
params['out_units'] = 'degC'
|
|
585
|
-
|
|
519
|
+
|
|
586
520
|
outdata = self.do_oa_base(params)
|
|
587
521
|
elif vartype.find('露点')>=0:
|
|
588
522
|
params={}
|
|
@@ -593,7 +527,7 @@ class Object_Analyst:
|
|
|
593
527
|
params['out_long_name'] = 'surface dewpoint temperature objective analyse'
|
|
594
528
|
params['out_short_name'] = 'oa_td'
|
|
595
529
|
params['out_units'] = 'degC'
|
|
596
|
-
|
|
530
|
+
|
|
597
531
|
outdata = self.do_oa_base(params)
|
|
598
532
|
elif vartype.find('湿度')>=0:
|
|
599
533
|
params={}
|
|
@@ -604,7 +538,7 @@ class Object_Analyst:
|
|
|
604
538
|
params['out_long_name'] = 'surface relative humidility objective analyse'
|
|
605
539
|
params['out_short_name'] = 'oa_rh'
|
|
606
540
|
params['out_units'] = '%'
|
|
607
|
-
|
|
541
|
+
|
|
608
542
|
outdata = self.do_oa_base(params)
|
|
609
543
|
|
|
610
544
|
# # wind
|
|
@@ -626,7 +560,7 @@ class Object_Analyst:
|
|
|
626
560
|
# params['out_long_name'] = '10m uwind objective analyse'
|
|
627
561
|
# params['out_short_name'] = 'oa_u10m'
|
|
628
562
|
# params['out_units'] = 'm/s'
|
|
629
|
-
#
|
|
563
|
+
#
|
|
630
564
|
# u10m = self.do_oa_base(params)
|
|
631
565
|
|
|
632
566
|
# # vwind
|
|
@@ -637,7 +571,7 @@ class Object_Analyst:
|
|
|
637
571
|
# params['out_long_name'] = '10m vwind objective analyse'
|
|
638
572
|
# params['out_short_name'] = 'oa_v10m'
|
|
639
573
|
# params['out_units'] = 'm/s'
|
|
640
|
-
#
|
|
574
|
+
#
|
|
641
575
|
# v10m = self.do_oa_base(params)
|
|
642
576
|
|
|
643
577
|
# digdata = self.calc_vor_div(wind_speed,wind_dir,lonlist,latlist)
|
|
@@ -646,258 +580,74 @@ class Object_Analyst:
|
|
|
646
580
|
|
|
647
581
|
return outdata
|
|
648
582
|
|
|
649
|
-
|
|
583
|
+
def calc_vor_div(self,wind_speed,wind_dir,lonlist,latlist):
|
|
650
584
|
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
# good_indices = np.where((~np.isnan(wind_dir)) & (~np.isnan(wind_speed)))
|
|
654
|
-
|
|
655
|
-
# x_masked = lonlist[good_indices]
|
|
656
|
-
# y_masked = latlist[good_indices]
|
|
657
|
-
# wind_speed = wind_speed[good_indices]
|
|
658
|
-
# wind_dir = wind_dir[good_indices]
|
|
659
|
-
# u, v = wind_components(wind_speed, wind_dir)
|
|
660
|
-
# windgridx, windgridy, uwind = interpolate_to_grid(x_masked, y_masked, np.array(u),interp_type='cressman', hres=self.reso)
|
|
661
|
-
|
|
662
|
-
# _, _, vwind = interpolate_to_grid(x_masked, y_masked, np.array(v), interp_type='cressman',hres=self.reso)
|
|
663
|
-
# if self.debug_level > 0:
|
|
664
|
-
# print('interpolate done!')
|
|
665
|
-
|
|
666
|
-
# # %%计算涡度散度
|
|
667
|
-
# dx, dy = lat_lon_grid_deltas(longitude=windgridx, latitude=windgridy)
|
|
668
|
-
# vtx=vorticity(u=uwind*units.meter/units.seconds ,v=vwind*units.meter/units.seconds,dx=dx,dy=dy)
|
|
669
|
-
# div=divergence(u=uwind*units.meter/units.seconds ,v=vwind*units.meter/units.seconds,dx=dx,dy=dy)
|
|
670
|
-
|
|
671
|
-
# # 乘上1e5,方便显示
|
|
672
|
-
# vtx = vtx * 1e5
|
|
673
|
-
# div = div * 1e5
|
|
674
|
-
# # print(vtx.shape)
|
|
675
|
-
# # print(div.shape)
|
|
676
|
-
# if self.debug_level > 0:
|
|
677
|
-
# print('涡度和散度计算完毕!')
|
|
678
|
-
|
|
679
|
-
# # 构建xarray,并返回
|
|
680
|
-
|
|
681
|
-
# # define coordinates
|
|
682
|
-
# # time_coord = ('time', redic['time'][0])
|
|
683
|
-
# lon_coord = ('lon', windgridx[0,:], {
|
|
684
|
-
# 'long_name':'longitude', 'units':'degrees_east', '_CoordinateAxisType':'Lon'})
|
|
685
|
-
# lat_coord = ('lat', windgridy[:,0], {
|
|
686
|
-
# 'long_name':'latitude', 'units':'degrees_north', '_CoordinateAxisType':'Lat'})
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
# # create xarray
|
|
690
|
-
# varattrs_vtx10m={'long_name': 'surface vortex ', 'short_name': 'oa_vtx_10m', 'units': '1e-5*1/s'}
|
|
691
|
-
# varattrs_div10m={'long_name': 'surface divergence ', 'short_name': 'oa_div_10m', 'units': '1e-5*1/s'}
|
|
692
|
-
|
|
693
|
-
# result = xr.Dataset({
|
|
694
|
-
# 'vtx_10m':(['lat', 'lon'], vtx.magnitude, varattrs_vtx10m),
|
|
695
|
-
# 'div_10m':(['lat', 'lon'], div.magnitude, varattrs_div10m),
|
|
696
|
-
# },
|
|
697
|
-
# coords={ 'lat':lat_coord, 'lon':lon_coord})
|
|
585
|
+
# 风场插值
|
|
698
586
|
|
|
699
|
-
|
|
700
|
-
# result.attrs['Conventions'] = "CF-1.6"
|
|
701
|
-
|
|
702
|
-
# # 对计算结果进行平滑处理
|
|
703
|
-
# vtx_smooth=result.vtx_10m.rolling(lon=5, lat=5, min_periods=1, center=True).mean()
|
|
704
|
-
# result.vtx_10m.data = vtx_smooth.values
|
|
705
|
-
|
|
706
|
-
# div_smooth=result.div_10m.rolling(lon=5, lat=5, min_periods=1, center=True).mean()
|
|
707
|
-
# result.div_10m.data = div_smooth.values
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
# pass
|
|
711
|
-
# return result
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
# # 显示客观分析结果
|
|
715
|
-
# def display_var(self,):
|
|
716
|
-
# # 显示
|
|
717
|
-
# to_proj = ccrs.LambertConformal(central_longitude=120, central_latitude=40)
|
|
718
|
-
# fig = plt.figure(figsize=(8, 7))
|
|
719
|
-
|
|
720
|
-
# view = fig.add_axes([0.05, 0.05, 0.9, 0.9]) # , projection=to_proj
|
|
721
|
-
# view.set_title('oa')
|
|
587
|
+
good_indices = np.where((~np.isnan(wind_dir)) & (~np.isnan(wind_speed)))
|
|
722
588
|
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
589
|
+
x_masked = lonlist[good_indices]
|
|
590
|
+
y_masked = latlist[good_indices]
|
|
591
|
+
wind_speed = wind_speed[good_indices]
|
|
592
|
+
wind_dir = wind_dir[good_indices]
|
|
593
|
+
u, v = wind_components(wind_speed, wind_dir)
|
|
594
|
+
windgridx, windgridy, uwind = interpolate_to_grid(x_masked, y_masked, np.array(u),interp_type='cressman', hres=self.reso)
|
|
727
595
|
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
596
|
+
_, _, vwind = interpolate_to_grid(x_masked, y_masked, np.array(v), interp_type='cressman',hres=self.reso)
|
|
597
|
+
if self.debug_level > 0:
|
|
598
|
+
print('interpolate done!')
|
|
599
|
+
|
|
600
|
+
# 计算涡度散度
|
|
601
|
+
dx, dy = lat_lon_grid_deltas(longitude=windgridx, latitude=windgridy)
|
|
602
|
+
vtx=vorticity(u=uwind*units.meter/units.seconds ,v=vwind*units.meter/units.seconds,dx=dx,dy=dy)
|
|
603
|
+
div=divergence(u=uwind*units.meter/units.seconds ,v=vwind*units.meter/units.seconds,dx=dx,dy=dy)
|
|
604
|
+
|
|
605
|
+
# 乘上1e5,方便显示
|
|
606
|
+
vtx = vtx * 1e5
|
|
607
|
+
div = div * 1e5
|
|
608
|
+
# print(vtx.shape)
|
|
609
|
+
# print(div.shape)
|
|
610
|
+
if self.debug_level > 0:
|
|
611
|
+
print('涡度和散度计算完毕!')
|
|
742
612
|
|
|
743
|
-
|
|
744
|
-
# # plt.show()
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
# 将等值线转换成gr2的格式
|
|
748
|
-
def trans_gr2(self,data,outpath,outname,badd_time_flag=False,m_pret=None,aws_duration=6,bhistory=False,encoding='gbk'):
|
|
749
|
-
'''
|
|
750
|
-
m_pret: 上一次的时间,用于历史数据构造
|
|
751
|
-
badd_time_flag : 是否需要添加时间信息
|
|
752
|
-
aws_duration: 数据持续显示的时间,单位分钟
|
|
753
|
-
bhistory: 是否是历史批处理模式
|
|
754
|
-
'''
|
|
755
|
-
varname = list(data.variables)[0]
|
|
756
|
-
|
|
757
|
-
# if maxvalue is None or minvalue is None:
|
|
758
|
-
# LEVS = np.linspace(np.nanmin(data[varname].values.flatten()),np.nanmax(data[varname].values.flatten()),len(colors_gr2))
|
|
759
|
-
# else:
|
|
760
|
-
# LEVS = np.linspace(minvalue,maxvalue,len(colors_gr2))
|
|
761
|
-
|
|
762
|
-
tipname = data.attrs['tipname']
|
|
763
|
-
if data.attrs['varname'] == 'sprs2m':
|
|
764
|
-
ccolors = get_colordf_from_file()
|
|
765
|
-
LEVS = np.arange(data.sta_minvalue,data.sta_maxvalue,2.5)
|
|
766
|
-
LEVS = LEVS.round(2)
|
|
767
|
-
if len(LEVS) > ccolors.shape[0]-1:
|
|
768
|
-
LEVS = LEVS[0:ccolors.shape[0]-1]
|
|
769
|
-
bb = np.linspace(0,ccolors.shape[0]-1,len(LEVS)).astype(int)
|
|
770
|
-
colors_gr2_new =[]
|
|
771
|
-
for i in bb:
|
|
772
|
-
colors_gr2_new.append(ccolors.iloc[i,:].values)
|
|
773
|
-
elif data.attrs['varname'].find('t2m_delta')>=0:
|
|
774
|
-
ccolors = get_colordf_from_file()
|
|
775
|
-
LEVS = np.arange(data.sta_minvalue,data.sta_maxvalue,0.5)
|
|
776
|
-
LEVS = LEVS.round(2)
|
|
777
|
-
if len(LEVS) > ccolors.shape[0]-1:
|
|
778
|
-
LEVS = LEVS[0:ccolors.shape[0]-1]
|
|
779
|
-
bb = np.linspace(0,ccolors.shape[0]-1,len(LEVS)).astype(int)
|
|
780
|
-
colors_gr2_new =[]
|
|
781
|
-
for i in bb:
|
|
782
|
-
colors_gr2_new.append(ccolors.iloc[i,:].values)
|
|
783
|
-
elif data.attrs['varname'].find('sprs2m_delta')>=0:
|
|
784
|
-
ccolors = get_colordf_from_file()
|
|
785
|
-
LEVS = np.arange(data.sta_minvalue,data.sta_maxvalue,0.1)
|
|
786
|
-
LEVS = LEVS.round(2)
|
|
787
|
-
if len(LEVS) > ccolors.shape[0]-1:
|
|
788
|
-
LEVS = LEVS[0:ccolors.shape[0]-1]
|
|
789
|
-
bb = np.linspace(0,ccolors.shape[0]-1,len(LEVS)).astype(int)
|
|
790
|
-
colors_gr2_new =[]
|
|
791
|
-
for i in bb:
|
|
792
|
-
colors_gr2_new.append(ccolors.iloc[i,:].values)
|
|
793
|
-
else:
|
|
794
|
-
colors_gr2_new = colors_gr2
|
|
795
|
-
LEVS = np.linspace(data.sta_minvalue,data.sta_maxvalue,len(colors_gr2_new))
|
|
796
|
-
#
|
|
797
|
-
if np.mean(abs(LEVS)) > 1:
|
|
798
|
-
if data.attrs['varname'] != 'sprs2m' and data.attrs['varname'].find('t2m_delta')<0 and data.attrs['varname'].find('sprs2m_delta')<0:
|
|
799
|
-
LEVS = LEVS.astype(int)
|
|
800
|
-
if LEVS[-1] - LEVS[0]<len(LEVS):
|
|
801
|
-
LEVS = np.linspace(LEVS[0],LEVS[0]+len(colors_gr2_new)-1,len(colors_gr2_new))
|
|
802
|
-
LEVS = LEVS.astype(int)
|
|
613
|
+
# 构建xarray,并返回
|
|
803
614
|
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
615
|
+
# define coordinates
|
|
616
|
+
# time_coord = ('time', redic['time'][0])
|
|
617
|
+
lon_coord = ('lon', windgridx[0,:], {
|
|
618
|
+
'long_name':'longitude', 'units':'degrees_east', '_CoordinateAxisType':'Lon'})
|
|
619
|
+
lat_coord = ('lat', windgridy[:,0], {
|
|
620
|
+
'long_name':'latitude', 'units':'degrees_north', '_CoordinateAxisType':'Lat'})
|
|
809
621
|
|
|
810
|
-
ax = plt.subplot()
|
|
811
|
-
|
|
812
|
-
pass
|
|
813
|
-
|
|
814
|
-
con_re = ax.contour(data.lat.values, data.lon.values, data[varname].values, LEVS,colors='k')
|
|
815
|
-
|
|
816
|
-
conts = get_contour_verts(con_re)
|
|
817
622
|
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
623
|
+
# create xarray
|
|
624
|
+
varattrs_vtx10m={'long_name': 'surface vortex ', 'short_name': 'oa_vtx_10m', 'units': '1e-5*1/s'}
|
|
625
|
+
varattrs_div10m={'long_name': 'surface divergence ', 'short_name': 'oa_div_10m', 'units': '1e-5*1/s'}
|
|
626
|
+
|
|
627
|
+
result = xr.Dataset({
|
|
628
|
+
'vtx_10m':(['lat', 'lon'], vtx.magnitude, varattrs_vtx10m),
|
|
629
|
+
'div_10m':(['lat', 'lon'], div.magnitude, varattrs_div10m),
|
|
630
|
+
},
|
|
631
|
+
coords={ 'lat':lat_coord, 'lon':lon_coord})
|
|
823
632
|
|
|
824
|
-
|
|
633
|
+
# add attributes
|
|
634
|
+
result.attrs['Conventions'] = "CF-1.6"
|
|
825
635
|
|
|
826
|
-
|
|
827
|
-
|
|
636
|
+
# 对计算结果进行平滑处理
|
|
637
|
+
vtx_smooth=result.vtx_10m.rolling(lon=5, lat=5, min_periods=1, center=True).mean()
|
|
638
|
+
result.vtx_10m.data = vtx_smooth.values
|
|
828
639
|
|
|
829
|
-
|
|
830
|
-
|
|
640
|
+
div_smooth=result.div_10m.rolling(lon=5, lat=5, min_periods=1, center=True).mean()
|
|
641
|
+
result.div_10m.data = div_smooth.values
|
|
831
642
|
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
# if bhistory:
|
|
835
|
-
# of.write('Refreshseconds: 30\n')
|
|
836
|
-
# of.write('Threshold: 999\n')
|
|
837
|
-
# of.write('Title: %s-等值线分析-%s(%s)\n'%(tipname,curtstr,self.time_type))
|
|
838
|
-
# of.write('Font: 1, 30, 1, "Arial"\n')
|
|
643
|
+
return result
|
|
839
644
|
|
|
840
|
-
if badd_time_flag:
|
|
841
|
-
|
|
842
|
-
# 这里直接用m_pret 可以保证不会出现重叠的记录
|
|
843
|
-
if not m_pret is None:
|
|
844
|
-
pre_time = m_pret + timedelta(minutes=-1*int(aws_duration/2))
|
|
845
|
-
endtime = m_pret + timedelta(minutes=1*int(aws_duration/2))
|
|
846
|
-
else:
|
|
847
|
-
pre_time = obstime + timedelta(minutes = - (obstime.minute % 6) -1*int(aws_duration/2))
|
|
848
|
-
endtime = obstime + timedelta(minutes=20)
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
timerangestr = 'TimeRange: ' + pre_time.strftime('%Y-%m-%dT%H:%M:%S') + ' ' + endtime.strftime('%Y-%m-%dT%H:%M:%S')
|
|
852
|
-
|
|
853
|
-
# 实时模式下,改时间一定要放在timerange后面
|
|
854
|
-
|
|
855
|
-
if self.time_type == "BJT":
|
|
856
|
-
pre_time = pre_time + timedelta(hours=8)
|
|
857
|
-
endtime = endtime + timedelta(hours=8)
|
|
858
|
-
|
|
859
|
-
if bhistory or not m_pret is None:
|
|
860
|
-
timerangestr = 'TimeRange: ' + pre_time.strftime('%Y-%m-%dT%H:%M:%S') + ' ' + endtime.strftime('%Y-%m-%dT%H:%M:%S')
|
|
861
|
-
|
|
862
|
-
of.write(timerangestr + '\n')
|
|
863
|
-
|
|
864
|
-
# 添加等值线
|
|
865
|
-
for lv in np.arange(0,len(LEVS)):
|
|
866
|
-
if lv >= len(conts):
|
|
867
|
-
continue
|
|
868
|
-
if LEVS[lv] == int(LEVS[lv]):
|
|
869
|
-
labs = str(int(LEVS[lv]))
|
|
870
|
-
else:
|
|
871
|
-
labs = '%.1f'%(LEVS[lv])
|
|
872
|
-
|
|
873
|
-
if len(conts[lv]) > 0:
|
|
874
|
-
for jj in np.arange(0,len(conts[lv])):
|
|
875
|
-
if conts[lv][jj].shape[0] < 5:
|
|
876
|
-
continue
|
|
877
|
-
else:
|
|
878
|
-
of.write('Color: %d %d %d\n'%(colors_gr2_new[lv][0], colors_gr2_new[lv][1], colors_gr2_new[lv][2]))
|
|
879
|
-
|
|
880
|
-
of.write('Line: 4,0,"%s等于%s等值线"\n'%(tipname,labs))
|
|
881
|
-
|
|
882
|
-
for kk in np.arange(0,conts[lv][jj].shape[0]): #
|
|
883
|
-
lat = conts[lv][jj][kk][0]
|
|
884
|
-
lon = conts[lv][jj][kk][1]
|
|
885
|
-
|
|
886
|
-
of.write('%.4f,%.4f\n'%(lat,lon))
|
|
887
|
-
of.write('End:\n')
|
|
888
|
-
for mm in np.arange(0,conts[lv][jj].shape[0],int(conts[lv][jj].shape[0]/2)):
|
|
889
|
-
of.write('Text: %.3f,%.3f,1,%s\n'%(conts[lv][jj][mm][0], conts[lv][jj][mm][1], labs))
|
|
890
|
-
of.write('\n')
|
|
891
|
-
plt.close('all')
|
|
892
|
-
plt.close()
|
|
893
|
-
gc.collect()
|
|
894
|
-
print(outpath + os.sep + outname + ' is done!')
|
|
895
|
-
pass
|
|
896
645
|
|
|
646
|
+
|
|
897
647
|
|
|
898
648
|
if __name__ == '__main__':
|
|
899
649
|
|
|
900
|
-
filepath = 'testdata/'
|
|
650
|
+
filepath = '/home/wjzhu/OneDrive/PythonCode/MyWork/metradar/testdata/aws/'
|
|
901
651
|
# filename = 'PLOT_5MIN_20220511141000.000'
|
|
902
652
|
filename = 'surface_aws_20230409_0818.csv'
|
|
903
653
|
startlon = 106
|
|
@@ -916,16 +666,16 @@ if __name__ == '__main__':
|
|
|
916
666
|
# result = oa_class.do_oa_mdfs(filepath + os.sep + filename,vartype='温度')
|
|
917
667
|
result = oa_class.do_oa_csv(filepath + os.sep + filename,vartype='温度')
|
|
918
668
|
|
|
919
|
-
oa_class.trans_gr2(result,'output/placefiles',list(result.variables)[0] + '.pls')
|
|
920
669
|
print('done! ')
|
|
921
670
|
|
|
922
671
|
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
672
|
+
if not result is None:
|
|
673
|
+
# cflag = (abs(result.t2m)<20) & (abs(result.t2m)>3)
|
|
674
|
+
result.t2m.plot.contourf(levels=15, add_colorbar=True)
|
|
675
|
+
plt.title('t2m')
|
|
676
|
+
plt.show()
|
|
677
|
+
|
|
678
|
+
kk=0
|
|
929
679
|
|
|
930
680
|
# if not result is None:
|
|
931
681
|
# cflag = (abs(result.div_10m)<20) & (abs(result.div_10m)>3)
|