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.
- metradar/__init__.py +7 -0
- metradar/cnrad_level2.py +1326 -0
- metradar/comm_func.py +135 -0
- metradar/construct_aws_refvpr_mainprog.py +515 -0
- metradar/construct_aws_refvpr_mainprog_cams.py +310 -0
- metradar/construct_aws_refvpr_mainprog_datan3d.py +386 -0
- metradar/construct_aws_refvpr_mainprog_swan.py +306 -0
- metradar/decode_fmt_pyart.py +200 -0
- metradar/decode_pup_rose.py +1993 -0
- metradar/draw_mosaic_new.py +421 -0
- metradar/draw_radar_aws_jilin_new.py +206 -0
- metradar/draw_radar_comp_func.py +1379 -0
- metradar/exceptions.py +50 -0
- metradar/geo_transforms_pyart.py +627 -0
- metradar/get_cross_section_from_pyart.py +354 -0
- metradar/get_tlogp_from_sharppy.py +93 -0
- metradar/grid.py +281 -0
- metradar/grid_data.py +64 -0
- metradar/main_pydda.py +653 -0
- metradar/make_gif.py +24 -0
- metradar/make_mosaic_mp_archive.py +538 -0
- metradar/mosaic_merge.py +64 -0
- metradar/mosaic_quickdraw.py +338 -0
- metradar/nowcast_by_pysteps.py +219 -0
- metradar/oa_couhua.py +166 -0
- metradar/oa_dig_func.py +955 -0
- metradar/parse_pal.py +148 -0
- metradar/pgmb_io.py +169 -0
- metradar/prepare_for_radar_draw.py +197 -0
- metradar/read_new_mosaic.py +33 -0
- metradar/read_new_mosaic_func.py +231 -0
- metradar/retrieve_cmadaas.py +3126 -0
- metradar/retrieve_micaps_server.py +2061 -0
- metradar/rose_structer.py +807 -0
- metradar/trans_nc_pgmb.py +62 -0
- metradar/trans_new_mosaic_nc.py +309 -0
- metradar/trans_polor2grid_func.py +203 -0
- metradar-0.1.0.dist-info/METADATA +12 -0
- metradar-0.1.0.dist-info/RECORD +41 -0
- metradar-0.1.0.dist-info/WHEEL +5 -0
- metradar-0.1.0.dist-info/top_level.txt +1 -0
metradar/grid.py
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import math
|
|
2
|
+
import datetime
|
|
3
|
+
import re
|
|
4
|
+
from copy import deepcopy
|
|
5
|
+
import numpy as np
|
|
6
|
+
|
|
7
|
+
class grid:
|
|
8
|
+
'''
|
|
9
|
+
定义一个格点的类grid,来存储网格的范围包括(起始经纬度、格距、起止时间,时间间隔,起止时效,时效间隔,层次列表,数据成员)
|
|
10
|
+
约定坐标顺序为: member, time,ddtime, level, lat,lon
|
|
11
|
+
'''
|
|
12
|
+
def __init__(self,glon, glat, gtime=None, dtime_list=None,level_list=None,member_list = None):
|
|
13
|
+
|
|
14
|
+
#提取成员维度信息
|
|
15
|
+
if(member_list is None):
|
|
16
|
+
self.members =['data0']
|
|
17
|
+
else:
|
|
18
|
+
self.members = member_list
|
|
19
|
+
############################################################################
|
|
20
|
+
#提取层次维度信息
|
|
21
|
+
if(level_list is None):
|
|
22
|
+
self.levels =[0]
|
|
23
|
+
else:
|
|
24
|
+
self.levels = level_list
|
|
25
|
+
############################################################################
|
|
26
|
+
#提取时间维度信息
|
|
27
|
+
self.stime = np.datetime64('2099-01-01T00:00:00.000000')
|
|
28
|
+
self.etime = np.datetime64('2099-01-01T00:00:00.000000')
|
|
29
|
+
self.dtime_int = 1
|
|
30
|
+
self.dtime_type = "h"
|
|
31
|
+
self.dtimedelta = np.timedelta64(1,'h')
|
|
32
|
+
if(gtime == None):gtime = []
|
|
33
|
+
if len(gtime) == 1:
|
|
34
|
+
if type(gtime[0]) == str:
|
|
35
|
+
num = ''.join([x for x in gtime[0] if x.isdigit()])
|
|
36
|
+
# 用户输入2019041910十位字符,后面补全加0000,为14位统一处理
|
|
37
|
+
if len(num) == 4:
|
|
38
|
+
num += "0101000000"
|
|
39
|
+
elif len(num) == 6:
|
|
40
|
+
num +="01000000"
|
|
41
|
+
elif len(num) == 8:
|
|
42
|
+
num +="000000"
|
|
43
|
+
elif len(num) == 10:
|
|
44
|
+
num +="0000"
|
|
45
|
+
elif len(num) == 12:
|
|
46
|
+
num +="00"
|
|
47
|
+
elif len(num) == 14:
|
|
48
|
+
pass
|
|
49
|
+
else:
|
|
50
|
+
print("输入日期有误,请检查!")
|
|
51
|
+
# 统一将日期变为datetime类型
|
|
52
|
+
self.stime = datetime.datetime.strptime(num, '%Y%m%d%H%M%S')
|
|
53
|
+
self.etime = datetime.datetime.strptime(num, '%Y%m%d%H%M%S')
|
|
54
|
+
self.stime = np.datetime64(self.stime)
|
|
55
|
+
self.etime = np.datetime64(self.etime)
|
|
56
|
+
else:
|
|
57
|
+
self.stime = gtime[0]
|
|
58
|
+
self.etime = gtime[0]
|
|
59
|
+
self.dtime_int = 1
|
|
60
|
+
self.dtime_type = "h"
|
|
61
|
+
self.dtimedelta = np.timedelta64(0,'h')
|
|
62
|
+
elif len(gtime) ==3:
|
|
63
|
+
num1 =[]
|
|
64
|
+
if type(gtime[0]) == str:
|
|
65
|
+
for i in range (0,2):
|
|
66
|
+
num = ''.join([x for x in gtime[i] if x.isdigit()])
|
|
67
|
+
#用户输入2019041910十位字符,后面补全加0000,为14位统一处理
|
|
68
|
+
if len(num) == 4:
|
|
69
|
+
num1.append(num + "0101000000")
|
|
70
|
+
elif len(num) == 6:
|
|
71
|
+
num1.append(num + "01000000")
|
|
72
|
+
elif len(num) == 8:
|
|
73
|
+
num1.append(num + "000000")
|
|
74
|
+
elif len(num) == 10:
|
|
75
|
+
num1.append(num + "0000")
|
|
76
|
+
elif len(num) == 12:
|
|
77
|
+
num1.append(num + "00")
|
|
78
|
+
elif len(num) == 14:
|
|
79
|
+
num1.append(num)
|
|
80
|
+
else:
|
|
81
|
+
print("输入日期有误,请检查!")
|
|
82
|
+
#统一将日期变为datetime类型
|
|
83
|
+
#print(num1)
|
|
84
|
+
self.stime = datetime.datetime.strptime(num1[0], '%Y%m%d%H%M%S')
|
|
85
|
+
self.etime = datetime.datetime.strptime(num1[1], '%Y%m%d%H%M%S')
|
|
86
|
+
self.stime = np.datetime64(self.stime)
|
|
87
|
+
self.etime = np.datetime64(self.etime)
|
|
88
|
+
elif isinstance(gtime[0],np.datetime64):
|
|
89
|
+
stime = gtime[0].astype(datetime.datetime)
|
|
90
|
+
etime = gtime[1].astype(datetime.datetime)
|
|
91
|
+
if isinstance(stime, int):
|
|
92
|
+
stime = datetime.datetime.utcfromtimestamp(stime / 1000000000)
|
|
93
|
+
etime = datetime.datetime.utcfromtimestamp(etime / 1000000000)
|
|
94
|
+
self.stime = stime
|
|
95
|
+
self.etime = etime
|
|
96
|
+
else:
|
|
97
|
+
self.stime = gtime[0]
|
|
98
|
+
self.etime = gtime[1]
|
|
99
|
+
|
|
100
|
+
if type(gtime[2]) == str:
|
|
101
|
+
self.dtime_int = re.findall(r"\d+", gtime[2])[0]
|
|
102
|
+
dtime_type = re.findall(r"\D+", gtime[2])[0]
|
|
103
|
+
if dtime_type == 'h':
|
|
104
|
+
self.dtime_type ="h"
|
|
105
|
+
self.dtimedelta = np.timedelta64(self.dtime_int,'h')
|
|
106
|
+
elif dtime_type == 'd':
|
|
107
|
+
self.dtime_type ="D"
|
|
108
|
+
self.dtimedelta = np.timedelta64(self.dtime_int, 'D')
|
|
109
|
+
elif dtime_type == 'm':
|
|
110
|
+
self.dtime_type ="m"
|
|
111
|
+
self.dtimedelta = np.timedelta64(self.dtime_int, 'm')
|
|
112
|
+
elif isinstance(gtime[2],np.timedelta64):
|
|
113
|
+
seconds = int(gtime[2] / np.timedelta64(1, 's'))
|
|
114
|
+
if seconds % 3600 == 0:
|
|
115
|
+
self.dtime_type = "h"
|
|
116
|
+
self.dtime_int = int(seconds / 3600)
|
|
117
|
+
else:
|
|
118
|
+
self.dtime_type = "m"
|
|
119
|
+
self.dtime_int = int(seconds / 60)
|
|
120
|
+
else:
|
|
121
|
+
self.dtimedelta = gtime[2]
|
|
122
|
+
seconds = gtime[2].total_seconds()
|
|
123
|
+
if seconds % 3600 == 0:
|
|
124
|
+
self.dtime_type = "h"
|
|
125
|
+
self.dtime_int = int(seconds/3600)
|
|
126
|
+
else:
|
|
127
|
+
self.dtime_type = "m"
|
|
128
|
+
self.dtime_int = int(seconds / 60)
|
|
129
|
+
self.gtime = [self.stime,self.etime,str(self.dtime_int) + self.dtime_type]
|
|
130
|
+
self.stime_str = str(self.stime).replace("-","").replace(" ","").replace(":","").replace("T","")[0:14]
|
|
131
|
+
self.etime_str = str(self.etime).replace("-", "").replace(" ", "").replace(":", "").replace("T", "")[0:14]
|
|
132
|
+
self.dtime_str = str(self.dtime_int) + self.dtime_type
|
|
133
|
+
|
|
134
|
+
############################################################################
|
|
135
|
+
#提取预报时效维度信息
|
|
136
|
+
if dtime_list is None:
|
|
137
|
+
self.dtimes = [0]
|
|
138
|
+
else:
|
|
139
|
+
self.dtimes = dtime_list
|
|
140
|
+
############################################################################
|
|
141
|
+
#提取经度信息
|
|
142
|
+
|
|
143
|
+
self.slon = get_true_value(glon[0])
|
|
144
|
+
self.elon = get_true_value(glon[1])
|
|
145
|
+
self.dlon = get_true_value(glon[2])
|
|
146
|
+
nlon = 1 + (self.elon - self.slon) / self.dlon
|
|
147
|
+
error = abs(round(nlon) - nlon)/nlon
|
|
148
|
+
if (error > 0.01):
|
|
149
|
+
self.nlon = int(math.ceil(nlon))
|
|
150
|
+
else:
|
|
151
|
+
self.nlon = int(round(nlon))
|
|
152
|
+
|
|
153
|
+
self.elon = get_true_value(self.slon + (nlon - 1) * self.dlon)
|
|
154
|
+
self.glon = [self.slon,self.elon,self.dlon]
|
|
155
|
+
|
|
156
|
+
############################################################################
|
|
157
|
+
#提取纬度信息
|
|
158
|
+
self.slat = get_true_value(glat[0])
|
|
159
|
+
self.elat = get_true_value(glat[1])
|
|
160
|
+
self.dlat = get_true_value(glat[2])
|
|
161
|
+
nlat = 1 + (self.elat - self.slat) / self.dlat
|
|
162
|
+
error = abs(round(nlat) - nlat)/nlat
|
|
163
|
+
if (error > 0.01):
|
|
164
|
+
self.nlat = int(math.ceil(nlat))
|
|
165
|
+
else:
|
|
166
|
+
self.nlat = int(round(nlat))
|
|
167
|
+
self.elat = get_true_value(self.slat + (nlat - 1) * self.dlat)
|
|
168
|
+
self.glat = [self.slat,self.elat,self.dlat]
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
#对原有的格点数据进行一次深拷贝,不改变原有的值和结构。
|
|
173
|
+
def copy(self):
|
|
174
|
+
return deepcopy(self)
|
|
175
|
+
|
|
176
|
+
#reset的作用是把网格的坐标间隔统一为正数。
|
|
177
|
+
def reset(self):
|
|
178
|
+
if (self.dlon > 0 and self.dlat > 0):
|
|
179
|
+
pass
|
|
180
|
+
if (self.dlat < 0):
|
|
181
|
+
tran = self.slat
|
|
182
|
+
self.slat = self.elat
|
|
183
|
+
self.elat = tran
|
|
184
|
+
self.dlat = abs(self.dlat)
|
|
185
|
+
if (self.dlon < 0):
|
|
186
|
+
tran = self.slon
|
|
187
|
+
self.slon = self.elon
|
|
188
|
+
self.elon = tran
|
|
189
|
+
self.dlon = abs(self.dlon)
|
|
190
|
+
return
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def __str__(self):
|
|
194
|
+
'''
|
|
195
|
+
重置系统自动的函数,在print(grid) 的时候可以很整齐的看到所有信息
|
|
196
|
+
:return: string
|
|
197
|
+
'''
|
|
198
|
+
grid_str = ""
|
|
199
|
+
grid_str += "members:" + str(self.members) +"\n"
|
|
200
|
+
grid_str += "levels:" + str(self.levels) + "\n"
|
|
201
|
+
grid_str += "gtime:" + str([self.stime_str,self.etime_str,self.dtime_str]) + "\n"
|
|
202
|
+
grid_str += "dtimes:" + str(self.dtimes) +"\n"
|
|
203
|
+
grid_str += "glon:" + str(self.glon) + "\n"
|
|
204
|
+
grid_str += "glat:" + str(self.glat) + "\n"
|
|
205
|
+
return grid_str
|
|
206
|
+
|
|
207
|
+
def get_true_value(value):
|
|
208
|
+
dlon2 = round(value, 2)
|
|
209
|
+
dlon3 = round(value, 3)
|
|
210
|
+
dlon4 = round(value, 4)
|
|
211
|
+
dlon5 = round(value, 5)
|
|
212
|
+
if dlon2 == dlon3 and dlon3 == dlon4:
|
|
213
|
+
return dlon3
|
|
214
|
+
elif dlon3 == dlon4 and dlon5 == dlon4:
|
|
215
|
+
return dlon3
|
|
216
|
+
else:
|
|
217
|
+
return value
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
def get_grid_of_data(grid_data0):
|
|
221
|
+
'''
|
|
222
|
+
获取grid的数据values值
|
|
223
|
+
:param grid_data0:初始化之后的网格数据
|
|
224
|
+
:return:返回grid数据。
|
|
225
|
+
'''
|
|
226
|
+
member_list = grid_data0['member'].values
|
|
227
|
+
level_list = grid_data0['level'].values
|
|
228
|
+
times = grid_data0['time'].values
|
|
229
|
+
#print(times)
|
|
230
|
+
if(len(times)>1):
|
|
231
|
+
gtime = [times[0],times[-1],times[1]-times[0]]
|
|
232
|
+
elif len(times) == 1:
|
|
233
|
+
gtime = times
|
|
234
|
+
else:
|
|
235
|
+
gtime = None
|
|
236
|
+
|
|
237
|
+
gdt = grid_data0['dtime'].values.tolist()
|
|
238
|
+
attrs_name = list(grid_data0.attrs)
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
lons = grid_data0['lon'].values
|
|
242
|
+
|
|
243
|
+
#dlon5 = round(lons[1] - lons[0], 5)
|
|
244
|
+
#dlon6 = round(lons[1] - lons[0], 6)
|
|
245
|
+
#dlon7 = round(lons[1] - lons[0], 7)
|
|
246
|
+
#if dlon5 == dlon6 and dlon6 == dlon7:
|
|
247
|
+
# dlon = dlon5
|
|
248
|
+
#else:
|
|
249
|
+
# dlon = lons[1]-lons[0]
|
|
250
|
+
dlon = get_true_value(lons[1] - lons[0])
|
|
251
|
+
|
|
252
|
+
#glon = [lons[0],round(lons[-1],5),round(lons[1]-lons[0],5)]
|
|
253
|
+
glon = [get_true_value(lons[0]), get_true_value(lons[-1]), dlon]
|
|
254
|
+
lats = grid_data0['lat'].values
|
|
255
|
+
#dlat5 = round(lats[1] - lats[0], 5)
|
|
256
|
+
#dlat6 = round(lats[1] - lats[0], 6)
|
|
257
|
+
#dlat7 = round(lats[1] - lats[0], 7)
|
|
258
|
+
#if dlat5 == dlat6 and dlat6 == dlat7:
|
|
259
|
+
# dlat = dlat5
|
|
260
|
+
#else:
|
|
261
|
+
# dlat = lats[1]-lats[0]
|
|
262
|
+
dlat = get_true_value(lats[1] - lats[0])
|
|
263
|
+
|
|
264
|
+
#glat = [lats[0],round(lats[-1],5),round(lats[1]-lats[0],5)]
|
|
265
|
+
glat = [get_true_value(lats[0]), get_true_value(lats[-1]), dlat]
|
|
266
|
+
grid01 = grid(glon, glat, gtime, gdt, level_list, member_list)
|
|
267
|
+
return grid01
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
def reset_grid(grid0):
|
|
271
|
+
if grid0.dlat <0:
|
|
272
|
+
grid0.dlat = - grid0.dlat
|
|
273
|
+
tran = grid0.slat
|
|
274
|
+
grid0.slat = grid0.elat
|
|
275
|
+
grid0.elat = tran
|
|
276
|
+
if grid0.dlon <0:
|
|
277
|
+
grid0.dlon = - grid0.dlon
|
|
278
|
+
tran = grid0.slon
|
|
279
|
+
grid0.slon = grid0.elon
|
|
280
|
+
grid0.elon = tran
|
|
281
|
+
return
|
metradar/grid_data.py
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
#!/usr/bin/python3.6
|
|
2
|
+
# -*- coding:UTF-8 -*-
|
|
3
|
+
import xarray as xr
|
|
4
|
+
import numpy as np
|
|
5
|
+
import pandas as pd
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
#返回一个DataArray,其维度信息和grid描述一致,数组里面的值为0.
|
|
9
|
+
def grid_data(grid,data=None):
|
|
10
|
+
slon = grid.slon
|
|
11
|
+
dlon = grid.dlon
|
|
12
|
+
slat = grid.slat
|
|
13
|
+
dlat = grid.dlat
|
|
14
|
+
nlon = grid.nlon
|
|
15
|
+
nlat = grid.nlat
|
|
16
|
+
# 通过起始经纬度和格距计算经纬度格点数
|
|
17
|
+
lon = np.arange(nlon) * dlon + slon
|
|
18
|
+
lat = np.arange(nlat) * dlat + slat
|
|
19
|
+
dt_str = grid.gtime[2]
|
|
20
|
+
if dt_str.find("m")>=0:
|
|
21
|
+
dt_str = dt_str.replace("m","min")
|
|
22
|
+
|
|
23
|
+
times = pd.date_range(grid.stime, grid.etime, freq=dt_str)
|
|
24
|
+
#print(times)
|
|
25
|
+
ntime = len(times)
|
|
26
|
+
# 根据timedelta的格式,算出ndt次数和gds时效列表
|
|
27
|
+
|
|
28
|
+
ndt = len(grid.dtimes)
|
|
29
|
+
gdt_list = grid.dtimes
|
|
30
|
+
|
|
31
|
+
level_list = grid.levels
|
|
32
|
+
nlevel_list = len(level_list)
|
|
33
|
+
|
|
34
|
+
member_list = grid.members
|
|
35
|
+
nmember = len(member_list)
|
|
36
|
+
if data is None:
|
|
37
|
+
data = np.zeros((nmember, nlevel_list, ntime, ndt, nlat, nlon))
|
|
38
|
+
else:
|
|
39
|
+
data = data.reshape(nmember, nlevel_list, ntime, ndt, nlat, nlon)
|
|
40
|
+
|
|
41
|
+
grd = (xr.DataArray(data, coords={'member': member_list,'level': level_list,'time': times,'dtime':gdt_list,
|
|
42
|
+
'lat': lat, 'lon': lon},
|
|
43
|
+
dims=['member', 'level','time', 'dtime','lat', 'lon']))
|
|
44
|
+
|
|
45
|
+
grd.name = "data0"
|
|
46
|
+
return grd
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def reset(grd):
|
|
50
|
+
lats = grd["lat"].values
|
|
51
|
+
if lats[0]>lats[1]:
|
|
52
|
+
lats = grd["lat"].values[::-1]
|
|
53
|
+
grd['lat'] = lats
|
|
54
|
+
dat = grd.values[:, :, :, :, ::-1, :]
|
|
55
|
+
grd.values = dat
|
|
56
|
+
|
|
57
|
+
lons = grd["lon"].values
|
|
58
|
+
if lons[0]>lons[1]:
|
|
59
|
+
lons = grd["lon"].values[::-1]
|
|
60
|
+
grd['lon'] = lons
|
|
61
|
+
dat = grd.values[:, :, :, :, :, ::-1]
|
|
62
|
+
grd.values = dat
|
|
63
|
+
|
|
64
|
+
return
|