metradar 0.1.3__tar.gz → 0.1.4__tar.gz
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-0.1.3 → metradar-0.1.4}/PKG-INFO +1 -1
- {metradar-0.1.3 → metradar-0.1.4}/metradar.egg-info/PKG-INFO +1 -1
- {metradar-0.1.3 → metradar-0.1.4}/metradar.egg-info/SOURCES.txt +0 -8
- {metradar-0.1.3 → metradar-0.1.4}/pyproject.toml +3 -2
- metradar-0.1.3/metradar/construct_aws_refvpr_mainprog.py +0 -515
- metradar-0.1.3/metradar/construct_aws_refvpr_mainprog_cams.py +0 -310
- metradar-0.1.3/metradar/construct_aws_refvpr_mainprog_datan3d.py +0 -386
- metradar-0.1.3/metradar/construct_aws_refvpr_mainprog_swan.py +0 -306
- metradar-0.1.3/metradar/draw_radar_aws_jilin_new.py +0 -206
- metradar-0.1.3/metradar/nowcast_by_pysteps.py +0 -219
- metradar-0.1.3/metradar/prepare_for_radar_draw.py +0 -197
- metradar-0.1.3/metradar/trans_polor2grid_func.py +0 -203
- {metradar-0.1.3 → metradar-0.1.4}/README.md +0 -0
- {metradar-0.1.3 → metradar-0.1.4}/metradar/__init__.py +0 -0
- {metradar-0.1.3 → metradar-0.1.4}/metradar/cnrad_level2.py +0 -0
- {metradar-0.1.3 → metradar-0.1.4}/metradar/comm_func.py +0 -0
- {metradar-0.1.3 → metradar-0.1.4}/metradar/decode_fmt_pyart.py +0 -0
- {metradar-0.1.3 → metradar-0.1.4}/metradar/decode_pup_rose.py +0 -0
- {metradar-0.1.3 → metradar-0.1.4}/metradar/draw_mosaic_new.py +0 -0
- {metradar-0.1.3 → metradar-0.1.4}/metradar/draw_radar_comp_func.py +0 -0
- {metradar-0.1.3 → metradar-0.1.4}/metradar/exceptions.py +0 -0
- {metradar-0.1.3 → metradar-0.1.4}/metradar/geo_transforms_pyart.py +0 -0
- {metradar-0.1.3 → metradar-0.1.4}/metradar/get_cross_section_from_pyart.py +0 -0
- {metradar-0.1.3 → metradar-0.1.4}/metradar/get_tlogp_from_sharppy.py +0 -0
- {metradar-0.1.3 → metradar-0.1.4}/metradar/grid.py +0 -0
- {metradar-0.1.3 → metradar-0.1.4}/metradar/grid_data.py +0 -0
- {metradar-0.1.3 → metradar-0.1.4}/metradar/main_pydda.py +0 -0
- {metradar-0.1.3 → metradar-0.1.4}/metradar/make_gif.py +0 -0
- {metradar-0.1.3 → metradar-0.1.4}/metradar/make_mosaic_mp_archive.py +0 -0
- {metradar-0.1.3 → metradar-0.1.4}/metradar/mosaic_merge.py +0 -0
- {metradar-0.1.3 → metradar-0.1.4}/metradar/mosaic_quickdraw.py +0 -0
- {metradar-0.1.3 → metradar-0.1.4}/metradar/oa_couhua.py +0 -0
- {metradar-0.1.3 → metradar-0.1.4}/metradar/oa_dig_func.py +0 -0
- {metradar-0.1.3 → metradar-0.1.4}/metradar/parse_pal.py +0 -0
- {metradar-0.1.3 → metradar-0.1.4}/metradar/pgmb_io.py +0 -0
- {metradar-0.1.3 → metradar-0.1.4}/metradar/read_new_mosaic.py +0 -0
- {metradar-0.1.3 → metradar-0.1.4}/metradar/read_new_mosaic_func.py +0 -0
- {metradar-0.1.3 → metradar-0.1.4}/metradar/retrieve_cmadaas.py +0 -0
- {metradar-0.1.3 → metradar-0.1.4}/metradar/retrieve_micaps_server.py +0 -0
- {metradar-0.1.3 → metradar-0.1.4}/metradar/rose_structer.py +0 -0
- {metradar-0.1.3 → metradar-0.1.4}/metradar/trans_nc_pgmb.py +0 -0
- {metradar-0.1.3 → metradar-0.1.4}/metradar/trans_new_mosaic_nc.py +0 -0
- {metradar-0.1.3 → metradar-0.1.4}/metradar.egg-info/dependency_links.txt +0 -0
- {metradar-0.1.3 → metradar-0.1.4}/metradar.egg-info/requires.txt +0 -0
- {metradar-0.1.3 → metradar-0.1.4}/metradar.egg-info/top_level.txt +0 -0
- {metradar-0.1.3 → metradar-0.1.4}/setup.cfg +0 -0
|
@@ -3,14 +3,9 @@ pyproject.toml
|
|
|
3
3
|
metradar/__init__.py
|
|
4
4
|
metradar/cnrad_level2.py
|
|
5
5
|
metradar/comm_func.py
|
|
6
|
-
metradar/construct_aws_refvpr_mainprog.py
|
|
7
|
-
metradar/construct_aws_refvpr_mainprog_cams.py
|
|
8
|
-
metradar/construct_aws_refvpr_mainprog_datan3d.py
|
|
9
|
-
metradar/construct_aws_refvpr_mainprog_swan.py
|
|
10
6
|
metradar/decode_fmt_pyart.py
|
|
11
7
|
metradar/decode_pup_rose.py
|
|
12
8
|
metradar/draw_mosaic_new.py
|
|
13
|
-
metradar/draw_radar_aws_jilin_new.py
|
|
14
9
|
metradar/draw_radar_comp_func.py
|
|
15
10
|
metradar/exceptions.py
|
|
16
11
|
metradar/geo_transforms_pyart.py
|
|
@@ -23,12 +18,10 @@ metradar/make_gif.py
|
|
|
23
18
|
metradar/make_mosaic_mp_archive.py
|
|
24
19
|
metradar/mosaic_merge.py
|
|
25
20
|
metradar/mosaic_quickdraw.py
|
|
26
|
-
metradar/nowcast_by_pysteps.py
|
|
27
21
|
metradar/oa_couhua.py
|
|
28
22
|
metradar/oa_dig_func.py
|
|
29
23
|
metradar/parse_pal.py
|
|
30
24
|
metradar/pgmb_io.py
|
|
31
|
-
metradar/prepare_for_radar_draw.py
|
|
32
25
|
metradar/read_new_mosaic.py
|
|
33
26
|
metradar/read_new_mosaic_func.py
|
|
34
27
|
metradar/retrieve_cmadaas.py
|
|
@@ -36,7 +29,6 @@ metradar/retrieve_micaps_server.py
|
|
|
36
29
|
metradar/rose_structer.py
|
|
37
30
|
metradar/trans_nc_pgmb.py
|
|
38
31
|
metradar/trans_new_mosaic_nc.py
|
|
39
|
-
metradar/trans_polor2grid_func.py
|
|
40
32
|
metradar.egg-info/PKG-INFO
|
|
41
33
|
metradar.egg-info/SOURCES.txt
|
|
42
34
|
metradar.egg-info/dependency_links.txt
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "metradar"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.4"
|
|
8
8
|
authors = [
|
|
9
9
|
{ name = "Wenjian Zhu", email = "kevin2075@163.com" }
|
|
10
10
|
]
|
|
@@ -45,4 +45,5 @@ requires-python = ">=3.10"
|
|
|
45
45
|
license-files = ["LICENSE"]
|
|
46
46
|
|
|
47
47
|
[tool.setuptools.packages.find]
|
|
48
|
-
include = ["metradar*"]
|
|
48
|
+
include = ["metradar*"]
|
|
49
|
+
exclude = ["tests*"]
|
|
@@ -1,515 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
'''
|
|
4
|
-
@File : construct_aws_refvpr_mainprog.py
|
|
5
|
-
@Time : 2023/08/19 20:58:59
|
|
6
|
-
@Author : Wenjian Zhu
|
|
7
|
-
@Version : 1.0
|
|
8
|
-
@Email : kevin2075@163.com
|
|
9
|
-
'''
|
|
10
|
-
|
|
11
|
-
from retrieve_cmadaas import cmadaas_obs_by_time_range_and_id,cmadaas_get_radar_vol,cmadaas_sounding_by_time
|
|
12
|
-
import pandas as pd
|
|
13
|
-
import geo_transforms_pyart as geotrans
|
|
14
|
-
import math
|
|
15
|
-
import numpy as np
|
|
16
|
-
import os
|
|
17
|
-
import configparser
|
|
18
|
-
from make_mosaic_mp_archive import MAKE_RADAR_MOSAIC
|
|
19
|
-
from multiprocessing import freeze_support
|
|
20
|
-
from datetime import datetime,timedelta
|
|
21
|
-
import xarray as xr
|
|
22
|
-
import numpy.ma as MA
|
|
23
|
-
import matplotlib.pyplot as plt
|
|
24
|
-
from parse_pal import parse_pro
|
|
25
|
-
from matplotlib.ticker import (MultipleLocator)
|
|
26
|
-
from matplotlib import font_manager
|
|
27
|
-
import matplotlib
|
|
28
|
-
from comm_func import geopotential_to_height
|
|
29
|
-
matplotlib.use('agg')
|
|
30
|
-
# 一键生成VPR数据和自动站数据,并绘制图形
|
|
31
|
-
#数据来源:天擎
|
|
32
|
-
|
|
33
|
-
class CONSTRUCT_VPR:
|
|
34
|
-
|
|
35
|
-
# sub function for reading config file
|
|
36
|
-
def ConfigFetchError(Exception):
|
|
37
|
-
pass
|
|
38
|
-
|
|
39
|
-
def _get_config_from_rcfile(self,rcfile):
|
|
40
|
-
"""
|
|
41
|
-
Get configure information from config_dk_met_io.ini file.
|
|
42
|
-
"""
|
|
43
|
-
|
|
44
|
-
rc = rcfile
|
|
45
|
-
print(rc)
|
|
46
|
-
if not os.path.exists(rc):
|
|
47
|
-
print(rc + ' not exist')
|
|
48
|
-
return None
|
|
49
|
-
try:
|
|
50
|
-
config = configparser.ConfigParser()
|
|
51
|
-
config.read(rc,encoding='UTF-8')
|
|
52
|
-
except IOError as e:
|
|
53
|
-
raise self.ConfigFetchError(str(e))
|
|
54
|
-
except Exception as e:
|
|
55
|
-
raise self.ConfigFetchError(str(e))
|
|
56
|
-
|
|
57
|
-
return config
|
|
58
|
-
|
|
59
|
-
def __init__(self,inifilepath) -> None:
|
|
60
|
-
pass
|
|
61
|
-
config = self._get_config_from_rcfile(inifilepath)
|
|
62
|
-
self.outpath = config['SETTINGS']['root_outpath']
|
|
63
|
-
self.outpath_fmt = self.outpath + os.sep + config['SETTINGS']['radar_basedata_path']
|
|
64
|
-
self.task_name = config['SETTINGS']['task_name']
|
|
65
|
-
|
|
66
|
-
self.start_time = config['SETTINGS']['starttime']
|
|
67
|
-
self.end_time = config['SETTINGS']['endtime']
|
|
68
|
-
self.staid = config['SETTINGS']['aws_site']
|
|
69
|
-
self.mosaic_range = int(config['SETTINGS']['mosaic_range'])
|
|
70
|
-
|
|
71
|
-
self.pic_format = config['SETTINGS']['pic_format']
|
|
72
|
-
self.pic_dpi = int(config['SETTINGS']['pic_dpi'])
|
|
73
|
-
self.colorfile = config['SETTINGS']['colorfile']
|
|
74
|
-
self.time_range = "[%s,%s]"%(self.start_time, self.end_time)
|
|
75
|
-
|
|
76
|
-
# self.tlogp_time = '20230731000000'
|
|
77
|
-
# 自动计算探空时间,用起始日期08时的探空
|
|
78
|
-
self.tlogp_time = self.start_time[0:8] + '000000'
|
|
79
|
-
|
|
80
|
-
self.outpath_tlogp = self.outpath + os.sep + 'tlogp'
|
|
81
|
-
self.outpath_sta = self.outpath + os.sep + 'VPR'
|
|
82
|
-
self.outpath_pic = self.outpath + os.sep + 'VPR'
|
|
83
|
-
self.outpath_ref = self.outpath + os.sep + 'VPR'
|
|
84
|
-
self.outname_sta= '%s.csv'%self.staid
|
|
85
|
-
self.outname_ref = 'p3_vpr_%s_pyart.nc'%self.staid
|
|
86
|
-
self.outpath_mosaic = self.outpath + os.sep + 'mosaic' + os.sep + self.task_name
|
|
87
|
-
|
|
88
|
-
if not os.path.exists(self.outpath):
|
|
89
|
-
os.makedirs(self.outpath)
|
|
90
|
-
if not os.path.exists(self.outpath_fmt):
|
|
91
|
-
os.makedirs(self.outpath_fmt)
|
|
92
|
-
if not os.path.exists(self.outpath_tlogp):
|
|
93
|
-
os.makedirs(self.outpath_tlogp)
|
|
94
|
-
if not os.path.exists(self.outpath_sta):
|
|
95
|
-
os.makedirs(self.outpath_sta)
|
|
96
|
-
if not os.path.exists(self.outpath_pic):
|
|
97
|
-
os.makedirs(self.outpath_pic)
|
|
98
|
-
if not os.path.exists(self.outpath_ref):
|
|
99
|
-
os.makedirs(self.outpath_ref)
|
|
100
|
-
if not os.path.exists(self.outpath_mosaic):
|
|
101
|
-
os.makedirs(self.outpath_mosaic)
|
|
102
|
-
|
|
103
|
-
pass
|
|
104
|
-
|
|
105
|
-
# 第一步,从天擎下载自动站数据
|
|
106
|
-
def get_aws_data(self,):
|
|
107
|
-
# 读取自动站雨量数据
|
|
108
|
-
# A7606, A7607, A7055, A7617 重庆
|
|
109
|
-
# # 54501 斋堂, A1067 丰台千灵山 A1254 大兴庞各庄
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
elements='Station_Name,Station_Id_C,Station_Id_d,lat,lon,Datetime,PRE,PRE_1h'
|
|
113
|
-
|
|
114
|
-
data_code = 'SURF_CHN_MUL_MIN'
|
|
115
|
-
|
|
116
|
-
# 读取数据
|
|
117
|
-
data = cmadaas_obs_by_time_range_and_id(time_range=self.time_range, data_code = data_code,elements=elements,sta_ids = self.staid)
|
|
118
|
-
if data is None:
|
|
119
|
-
print('required data is None, please check the site number!')
|
|
120
|
-
return False
|
|
121
|
-
|
|
122
|
-
self.sta_lat = data['lat'][0]
|
|
123
|
-
self.sta_lon = data['lon'][0]
|
|
124
|
-
self.sta_name = data['Station_Name'][0]
|
|
125
|
-
|
|
126
|
-
# data.to_csv(outpath_sta + os.sep + outname_sta,index=False)
|
|
127
|
-
data2 = data.set_index('Datetime')
|
|
128
|
-
# data2['PRE_1h'][0]=0
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
diff_rain =[]
|
|
132
|
-
diff_rain.append(0)
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
# PRE_1h表示当前小时的累计雨量
|
|
136
|
-
# pre_5min表示当前5分钟的累计雨量
|
|
137
|
-
# pre_1min表示当前1分钟的累计雨量
|
|
138
|
-
# accsum表示从起始时刻到当前时刻的累计雨量
|
|
139
|
-
# 时间均为UTC时间
|
|
140
|
-
|
|
141
|
-
# diff()为求差,mode()为获取众数
|
|
142
|
-
# steps 为数据的时间间隔,单位为分钟
|
|
143
|
-
steps = int(data['Datetime'].diff().mode()[0].seconds/60)
|
|
144
|
-
difrain_name = 'pre_%dmin'%steps
|
|
145
|
-
for nn in np.arange(0,data2.shape[0]-1):
|
|
146
|
-
|
|
147
|
-
if data2['PRE_1h'][nn+1] >= data2['PRE_1h'][nn]:
|
|
148
|
-
diff_rain.append(round(data2['PRE_1h'][nn+1]-data2['PRE_1h'][nn],2))
|
|
149
|
-
else:
|
|
150
|
-
diff_rain.append(round(data2['PRE_1h'][nn+1],2))
|
|
151
|
-
newpd = pd.DataFrame(diff_rain,columns=[difrain_name],index=data2.index)
|
|
152
|
-
# 如果间隔是1分钟,那么还需要求出5分钟的雨量
|
|
153
|
-
if steps == 1:
|
|
154
|
-
newpd['pre_5min'] = newpd[difrain_name].rolling(5).sum()
|
|
155
|
-
newpd['pre_5min'] = newpd['pre_5min'].round(2)
|
|
156
|
-
else:
|
|
157
|
-
pass
|
|
158
|
-
newindex = [tt for tt in newpd.index if tt.minute%5==0]
|
|
159
|
-
newpd['accsum'] = newpd[difrain_name].cumsum()
|
|
160
|
-
newpd['accsum'] = newpd['accsum'].round(2)
|
|
161
|
-
newpd['PRE_1h'] = data2['PRE_1h']
|
|
162
|
-
newpd['PRE'] = data2['PRE']
|
|
163
|
-
newpd['lat'] = data2['lat']
|
|
164
|
-
newpd['lon'] = data2['lon']
|
|
165
|
-
newpd['staname']=data2['Station_Name']
|
|
166
|
-
newpd.to_csv(self.outpath_sta + os.sep + self.outname_sta,index=True,encoding='gbk')
|
|
167
|
-
return True
|
|
168
|
-
|
|
169
|
-
def get_tlogp_data(self,):
|
|
170
|
-
# 第二步,从离自动站最近的探空站中获取探空数据,提取零度层高度和-20度层高度
|
|
171
|
-
# 读取探空站信息,获取经纬度、站号等信息
|
|
172
|
-
# tlogpinfo = pd.read_csv('../common/stationinfo_new/china_tlogp_stations_m3.txt',delimiter=r"\s+",skiprows=3,names=['stanum','lon','lat','alt','num2'])
|
|
173
|
-
|
|
174
|
-
# tmpdata['stanum'].values[0] int
|
|
175
|
-
# staid_tlogp = str(tmpdata['stanum'].values[0])
|
|
176
|
-
tlogpdata = cmadaas_sounding_by_time(times=self.tlogp_time)
|
|
177
|
-
allstas = np.unique(tlogpdata['Station_Id_C'])
|
|
178
|
-
alllons=[]
|
|
179
|
-
alllats=[]
|
|
180
|
-
#获取所有站点的经纬度信息
|
|
181
|
-
for ts in allstas:
|
|
182
|
-
tmpd = tlogpdata[tlogpdata['Station_Id_C']==ts]
|
|
183
|
-
curlat = tmpd['Lat'].values[0]
|
|
184
|
-
curlon = tmpd['Lon'].values[0]
|
|
185
|
-
alllons.append(curlon)
|
|
186
|
-
alllats.append(curlat)
|
|
187
|
-
|
|
188
|
-
x,y= geotrans.geographic_to_cartesian_aeqd(lon=alllons,lat=alllats,lon_0=self.sta_lon,lat_0=self.sta_lat)
|
|
189
|
-
dis = [math.sqrt(pow(x[k],2) + pow(y[k],2))/1000 for k in range(len(x))]
|
|
190
|
-
flag = np.array(dis) <= min(dis)+0.1
|
|
191
|
-
tmpts = allstas[flag]
|
|
192
|
-
tmpdata = tlogpdata[tlogpdata['Station_Id_C']==tmpts[0]]
|
|
193
|
-
tmpdata = tmpdata.sort_values(by='PRS_HWC',ascending=False)
|
|
194
|
-
tmpdata.dropna(subset=['PRS_HWC'],inplace=True)
|
|
195
|
-
tmpdata.to_csv(self.outpath_tlogp + os.sep + 'tlogp_%s.csv'%tmpts[0],index=False)
|
|
196
|
-
#查找离零度层和-20度层最近的高度
|
|
197
|
-
flag = np.array(abs(tmpdata['TEM'])) <= abs(tmpdata['TEM']).min()+0.01
|
|
198
|
-
z0 = tmpdata['GPH'][flag].values[0]
|
|
199
|
-
flag = np.array(abs(tmpdata['TEM']+20)) <= abs(tmpdata['TEM']+20).min()+0.01
|
|
200
|
-
z20 = tmpdata['GPH'][flag].values[0]
|
|
201
|
-
|
|
202
|
-
self.z0 = geopotential_to_height(z0*9.80665)
|
|
203
|
-
self.z20 = geopotential_to_height(z20*9.80665)
|
|
204
|
-
return True
|
|
205
|
-
|
|
206
|
-
def get_fmt_data(self,):
|
|
207
|
-
# 第三步,从天擎读取雷达数据
|
|
208
|
-
# 先检查是否已经存在拼图文件,而且拼图文件中的时间和范围能够覆盖当前自动站
|
|
209
|
-
# 如果已经能满足要求,则不再下载雷达数据
|
|
210
|
-
startt = datetime.strptime(self.start_time,'%Y%m%d%H%M%S')
|
|
211
|
-
endt = datetime.strptime(self.end_time,'%Y%m%d%H%M%S')
|
|
212
|
-
curt = startt
|
|
213
|
-
allref=[]
|
|
214
|
-
grd_height = None
|
|
215
|
-
need_file_times=[]
|
|
216
|
-
while curt <= endt:
|
|
217
|
-
|
|
218
|
-
curname = 'mosaic_' + curt.strftime('%Y%m%d%H%M') + '.nc'
|
|
219
|
-
if os.path.exists(self.outpath_mosaic + os.sep + curname):
|
|
220
|
-
# print('file exist: %s'%(outpath_mosaic + os.sep + curname))
|
|
221
|
-
|
|
222
|
-
ref = xr.open_dataset(self.outpath_mosaic + os.sep + curname)
|
|
223
|
-
|
|
224
|
-
cent_lat = ref.origin_latitude.values[0]
|
|
225
|
-
cent_lon = ref.origin_longitude.values[0]
|
|
226
|
-
x,y= geotrans.geographic_to_cartesian_aeqd(lon=self.sta_lon,lat=self.sta_lat,lon_0=cent_lon,lat_0=cent_lat)
|
|
227
|
-
grd_height = ref['z'].values
|
|
228
|
-
reso_x = ref['x'][1]-ref['x'][0]
|
|
229
|
-
reso_y = ref['y'][1]-ref['y'][0]
|
|
230
|
-
xx = x[0]/reso_x
|
|
231
|
-
yy = y[0]/reso_y
|
|
232
|
-
xx = int(xx.round())
|
|
233
|
-
yy = int(yy.round())
|
|
234
|
-
radius = int((len(ref.x)-1)/2)
|
|
235
|
-
|
|
236
|
-
if xx+radius >=0 and xx+radius < len(ref.x) and yy+radius >=0 and yy+radius < len(ref.y):
|
|
237
|
-
pass
|
|
238
|
-
else:
|
|
239
|
-
# 表示当前拼图范围不能覆盖自动站,需要重新下载数据进行拼图
|
|
240
|
-
need_file_times.append(curt)
|
|
241
|
-
ref.close()
|
|
242
|
-
else:
|
|
243
|
-
need_file_times.append(curt)
|
|
244
|
-
curt += timedelta(minutes=6)
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
# 如果不能满足要求,则下载雷达数据
|
|
249
|
-
|
|
250
|
-
# 根据自动站经纬度,自动判断应该下载哪些雷达站的数据
|
|
251
|
-
# 读取雷达站点信息,获取经纬度、站号等信息
|
|
252
|
-
valid_range = 200
|
|
253
|
-
radinfo = pd.read_csv('metradar/radars.txt',sep='|',names=['radar_id','radar_name','gr2_name','radar_lat','radar_lon','radar_alt'],index_col=0)
|
|
254
|
-
|
|
255
|
-
x,y = geotrans.geographic_to_cartesian_aeqd(radinfo['radar_lon'],radinfo['radar_lat'],self.sta_lon,self.sta_lat, R=6370997.0)
|
|
256
|
-
# dis = math.sqrt(pow(x[0],2) + pow(y[0],2))
|
|
257
|
-
dis = [math.sqrt(pow(x[k],2) + pow(y[k],2))/1000 for k in range(len(x))]
|
|
258
|
-
flag = np.array(dis) <= valid_range
|
|
259
|
-
# flag = np.where(dis<=valid_range)[0]
|
|
260
|
-
tmpdata = radinfo.loc[flag]
|
|
261
|
-
self.rdinfo = tmpdata.loc[:,['radar_name','radar_lat','radar_lon']]
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
for site in self.rdinfo.index:
|
|
265
|
-
print(site)
|
|
266
|
-
# 从天擎下载该站号的雷达资料
|
|
267
|
-
if len(need_file_times) == 0:
|
|
268
|
-
# cmadaas_get_radar_vol(starttime=start_time,endtime=end_time,sta_ids=[site,],data_code= 'RADA_L2_FMT', outdir=outpath_fmt)
|
|
269
|
-
pass
|
|
270
|
-
else:
|
|
271
|
-
tmp_starttime = min(need_file_times).strftime('%Y%m%d%H%M%S')
|
|
272
|
-
tmp_endtime = max(need_file_times).strftime('%Y%m%d%H%M%S')
|
|
273
|
-
cmadaas_get_radar_vol(starttime=tmp_starttime,endtime=tmp_endtime,sta_ids=[site,],data_code= 'RADA_L2_FMT', outdir=self.outpath_fmt)
|
|
274
|
-
|
|
275
|
-
return True
|
|
276
|
-
# 第四步,制作区域三维拼图
|
|
277
|
-
def make_mosaic(self,):
|
|
278
|
-
# 修改配置文件
|
|
279
|
-
inifile_tmp = 'metradar/make_mosaic_mp_archive_vpr.ini'
|
|
280
|
-
config = configparser.ConfigParser()
|
|
281
|
-
config.read(inifile_tmp)
|
|
282
|
-
config.set('ARCHIVE', 'input_path_archive', self.outpath_fmt) #
|
|
283
|
-
config.set('ARCHIVE', 'output_path_archive', self.outpath_mosaic) #
|
|
284
|
-
config.set('ARCHIVE', 'starttime', self.start_time[0:12]) #
|
|
285
|
-
config.set('ARCHIVE', 'endtime', self.end_time[0:12]) #
|
|
286
|
-
config.set('COMMON_SETTING', 'center_lon', '%.3f'%self.sta_lon) #
|
|
287
|
-
config.set('COMMON_SETTING', 'center_lat', '%.3f'%self.sta_lat) #
|
|
288
|
-
config.set('COMMON_SETTING', 'mosaic_range', '50') #
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
str_site=''
|
|
292
|
-
for site in self.rdinfo.index:
|
|
293
|
-
str_site += site+','
|
|
294
|
-
config.set('COMMON_SETTING', 'radars', str_site) #
|
|
295
|
-
config.write(open(inifile_tmp, 'w')) # 将修改后的配置写入文件
|
|
296
|
-
|
|
297
|
-
_make_mosaic = MAKE_RADAR_MOSAIC(inifile_tmp)
|
|
298
|
-
|
|
299
|
-
if not _make_mosaic.berror:
|
|
300
|
-
if _make_mosaic.run_mode == 'archive':
|
|
301
|
-
_make_mosaic.do_archive()
|
|
302
|
-
else:
|
|
303
|
-
print('run mode is not archive!')
|
|
304
|
-
return True
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
# 第五步:从三维拼图数据中获取格点的时间序列
|
|
308
|
-
def make_vpr(self,):
|
|
309
|
-
|
|
310
|
-
data = pd.read_csv(self.outpath_sta+os.sep+self.outname_sta,index_col=0,encoding='gbk')
|
|
311
|
-
sta_lat = data['lat'][0]
|
|
312
|
-
sta_lon = data['lon'][0]
|
|
313
|
-
sta_name = data['staname'][0]
|
|
314
|
-
startt = datetime.strptime(self.start_time,'%Y%m%d%H%M%S')
|
|
315
|
-
endt = datetime.strptime(self.end_time,'%Y%m%d%H%M%S')
|
|
316
|
-
curt = startt
|
|
317
|
-
allref=[]
|
|
318
|
-
grd_height = None
|
|
319
|
-
file_times=[]
|
|
320
|
-
while curt <= endt:
|
|
321
|
-
|
|
322
|
-
curname = 'mosaic_' + curt.strftime('%Y%m%d%H%M') + '.nc'
|
|
323
|
-
if not os.path.exists(self.outpath_mosaic + os.sep + curname):
|
|
324
|
-
print('file not exist: %s'%(self.outpath_mosaic + os.sep + curname))
|
|
325
|
-
curt += timedelta(minutes=6)
|
|
326
|
-
continue
|
|
327
|
-
|
|
328
|
-
ref = xr.open_dataset(self.outpath_mosaic + os.sep + curname)
|
|
329
|
-
|
|
330
|
-
cent_lat = ref.origin_latitude.values[0]
|
|
331
|
-
cent_lon = ref.origin_longitude.values[0]
|
|
332
|
-
x,y= geotrans.geographic_to_cartesian_aeqd(lon=sta_lon,lat=sta_lat,lon_0=cent_lon,lat_0=cent_lat)
|
|
333
|
-
grd_height = ref['z'].values
|
|
334
|
-
reso_x = ref['x'][1]-ref['x'][0]
|
|
335
|
-
reso_y = ref['y'][1]-ref['y'][0]
|
|
336
|
-
xx = x[0]/reso_x
|
|
337
|
-
yy = y[0]/reso_y
|
|
338
|
-
xx = int(xx.round())
|
|
339
|
-
yy = int(yy.round())
|
|
340
|
-
radius = int((len(ref.x)-1)/2)
|
|
341
|
-
ref2 = ref.isel(x=xx+radius,y=yy+radius)['reflectivity'].values
|
|
342
|
-
# 对ref2进行线性插值
|
|
343
|
-
tmpdf = pd.DataFrame(ref2[0],columns=['ref_raw'])
|
|
344
|
-
tmpdf['ref_new'] = tmpdf['ref_raw'].interpolate(method='slinear')
|
|
345
|
-
ref2 = tmpdf['ref_new'].values
|
|
346
|
-
allref.append(ref2)
|
|
347
|
-
file_times.append(curt)
|
|
348
|
-
curt += timedelta(minutes=6)
|
|
349
|
-
ref.close()
|
|
350
|
-
allref = np.array(allref)
|
|
351
|
-
# allref = allref.reshape(allref.shape[0],allref.shape[2])
|
|
352
|
-
|
|
353
|
-
alldata = MA.masked_array(allref, mask=allref==-9999)
|
|
354
|
-
xrdata = xr.Dataset({
|
|
355
|
-
'dbz':(['z', 'time'], alldata.T, {'long name':'time-height dBZ'})},
|
|
356
|
-
coords={'z':grd_height, 'time':file_times},
|
|
357
|
-
attrs={'lat':sta_lat, 'lon':sta_lon})
|
|
358
|
-
|
|
359
|
-
xrdata.to_netcdf(self.outpath_ref + os.sep + self.outname_ref)
|
|
360
|
-
print('ref data success!')
|
|
361
|
-
return True
|
|
362
|
-
|
|
363
|
-
# 第六步,绘制图形
|
|
364
|
-
def draw_pic(self,):
|
|
365
|
-
oridf = pd.read_csv(self.outpath_sta+os.sep+self.outname_sta,encoding='gbk')#,index_col=0
|
|
366
|
-
|
|
367
|
-
oridf['Datetime'] = pd.to_datetime(oridf['Datetime'], format="%Y-%m-%d %H:%M:%S")
|
|
368
|
-
oridf = oridf.set_index('Datetime')
|
|
369
|
-
newindex = [tt for tt in oridf.index if tt.minute%5==0]
|
|
370
|
-
df = oridf.loc[newindex]
|
|
371
|
-
# df.set_index('staname',inplace=True)
|
|
372
|
-
df.reset_index(inplace=True)
|
|
373
|
-
|
|
374
|
-
#将缺失的时间进行插值处理
|
|
375
|
-
helper = pd.DataFrame({'Datetime': pd.date_range(start=df['Datetime'].min(), end=df['Datetime'].max(),freq='300s')})
|
|
376
|
-
newdf = pd.merge(df, helper, on='Datetime', how='outer').sort_values('Datetime')
|
|
377
|
-
newdf['accsum'] = newdf['accsum'].interpolate(method='linear')
|
|
378
|
-
|
|
379
|
-
# ref_colorfile='gr2_colors/default_BR_PUP1.pal'
|
|
380
|
-
# ref_colorfile = 'gr2_colors/BR_WDTB_Bright.pal'
|
|
381
|
-
outdic= parse_pro(self.colorfile)
|
|
382
|
-
cmap=outdic['cmap']
|
|
383
|
-
norm=outdic['norm']
|
|
384
|
-
units=outdic['units']
|
|
385
|
-
# from pyart.graph import common
|
|
386
|
-
# cmapname = 'pyart_NWSRef'
|
|
387
|
-
# cmap = common.parse_cmap(cmapname, 'reflectivity')
|
|
388
|
-
|
|
389
|
-
data = xr.open_dataset(self.outpath_ref + os.sep + self.outname_ref)
|
|
390
|
-
|
|
391
|
-
data = data.rolling(z=2, time=2, min_periods=1, center=True).mean()
|
|
392
|
-
|
|
393
|
-
font_path = 'resources/fonts/simsun.ttc'
|
|
394
|
-
font_manager.fontManager.addfont(font_path)
|
|
395
|
-
prop = font_manager.FontProperties(fname=font_path)
|
|
396
|
-
|
|
397
|
-
plt.rcParams["font.size"] = 12
|
|
398
|
-
plt.rcParams["font.sans-serif"] = prop.get_name()
|
|
399
|
-
fig = plt.figure(figsize=(10,6))
|
|
400
|
-
ax1 = fig.add_axes([0.1,0.18,0.8,0.3])#位置[左,下,右,上]
|
|
401
|
-
ax3 = fig.add_axes([0.1,0.64,0.8,0.3])#位置[左,下,右,上]
|
|
402
|
-
ax2 = ax3.twinx()
|
|
403
|
-
ax1.minorticks_on()
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
cb_ax = fig.add_axes([0.25, 0.08, 0.5, 0.03])
|
|
407
|
-
|
|
408
|
-
grid_y,grid_x=np.meshgrid(np.arange(0,data.dbz.shape[1]),data.z.values,)
|
|
409
|
-
pcm = ax1.pcolormesh(grid_y,grid_x,data.dbz,cmap=cmap,norm=norm)
|
|
410
|
-
# pcm = ax1.pcolormesh(data.dbz,cmap=cmap,norm=norm)
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
# flag = np.array(abs(data.z.values - z0)) <= abs(data.z.values - z0).min()+0.01
|
|
414
|
-
# z0h = ax1.plot(np.arange(0,data.dbz.shape[1]),np.ones(data.dbz.shape[1])*int(np.where(flag)[0][0]),'y--',
|
|
415
|
-
# linewidth=2,label='0度层高度')
|
|
416
|
-
# flag = np.array(abs(data.z.values - z20)) <= abs(data.z.values - z20).min()+0.01
|
|
417
|
-
# z20h=ax1.plot(np.arange(0,data.dbz.shape[1]),np.ones(data.dbz.shape[1])*int(np.where(flag)[0][0]),'r--',
|
|
418
|
-
# linewidth=2,label='-20度层高度')
|
|
419
|
-
z0h = ax1.plot(np.arange(0,data.dbz.shape[1]),np.ones(data.dbz.shape[1])*self.z0,'k--',linewidth=2,label='0度层高度')
|
|
420
|
-
z20h=ax1.plot(np.arange(0,data.dbz.shape[1]),np.ones(data.dbz.shape[1])*self.z20,'r--',linewidth=2,label='-20度层高度')
|
|
421
|
-
|
|
422
|
-
# leg = ax1.legend([z0h], ["零度层高度",], loc='upper right',title_fontproperties=prop)
|
|
423
|
-
ax1.legend()
|
|
424
|
-
ax1.tick_params(axis='x',which='minor',length=3,width=0.8,)
|
|
425
|
-
ax1.tick_params(axis='x',which='major',length=5,width=1,)
|
|
426
|
-
cb = plt.colorbar(mappable=pcm,cax=cb_ax,extend='both',ticks=np.arange(-10,85,5),orientation='horizontal')
|
|
427
|
-
cb.set_label('反射率因子 dBZ',fontsize=12)
|
|
428
|
-
ah1=ax2.plot(newdf['accsum'].values,'r',linewidth=2,label='累计雨量')
|
|
429
|
-
ah2=ax3.bar(np.arange(0,newdf.shape[0]),newdf['pre_5min'],label='5分钟雨量')
|
|
430
|
-
ax2.legend(loc='upper right')
|
|
431
|
-
ax3.legend(loc='upper left')
|
|
432
|
-
ax3.minorticks_on()
|
|
433
|
-
ax3.tick_params(axis='x',which='minor',length=3,width=0.8,)
|
|
434
|
-
ax3.tick_params(axis='x',which='major',length=5,width=1,)
|
|
435
|
-
ax3.xaxis.set_minor_locator(MultipleLocator(1))
|
|
436
|
-
ax1.set_xlim([0,data.dbz.shape[1]+1])
|
|
437
|
-
ax2.set_xlim([0,newdf.shape[0]])
|
|
438
|
-
ax1.grid('y')
|
|
439
|
-
ax2.grid('y')
|
|
440
|
-
# plt.xticks(fontsize=12)
|
|
441
|
-
# plt.yticks(fontsize=12)
|
|
442
|
-
# ax1.set_xlabel('Time(BJT, day hour:min)')
|
|
443
|
-
ax1.set_ylabel('距离地面的高度(米)')
|
|
444
|
-
ax1.set_title('单点回波强度时间-高度图(%.2f°N,%.2f°E)'%(data.lat,data.lon),fontsize=12)
|
|
445
|
-
ax2.set_ylabel('累计雨量(毫米)',color='r')
|
|
446
|
-
ax3.set_ylabel('5分钟雨量(毫米)',color=[59/255,117/255,175/255])
|
|
447
|
-
|
|
448
|
-
tmpdate = pd.to_datetime(data.time)+ timedelta(hours=8)
|
|
449
|
-
dates1 = [date.strftime('%H:%M') for date in tmpdate]
|
|
450
|
-
dates1[0] = tmpdate.min().strftime('%H:%M \n%Y-%m-%d')
|
|
451
|
-
|
|
452
|
-
datestr = dates1[::5]
|
|
453
|
-
tmpd = tmpdate[::5]
|
|
454
|
-
datestr[-1] = tmpd.max().strftime('%H:%M \n%Y-%m-%d')
|
|
455
|
-
|
|
456
|
-
ax1.set_xticks(np.arange(0,data.time.shape[0],5))
|
|
457
|
-
ax1.set_xticklabels(datestr)
|
|
458
|
-
# ax1.set_yticks(np.arange(0,data.z.shape[0],5))
|
|
459
|
-
# ax1.set_yticklabels(data.z[::5].values.astype('int'))
|
|
460
|
-
# ax1.set_yticks(data.z[::5])
|
|
461
|
-
# ax1.set_ylim([data.z.min(),data.z.max()])
|
|
462
|
-
ax1.set_ylim([0,20000])
|
|
463
|
-
ax1.set_yticks(np.arange(0,20000,2500))
|
|
464
|
-
|
|
465
|
-
tmpdate = pd.to_datetime(newdf['Datetime'])+ timedelta(hours=8)
|
|
466
|
-
dates2 = [date.strftime('%H:%M') for date in tmpdate]
|
|
467
|
-
dates2[0] = tmpdate.min().strftime('%H:%M \n%Y-%m-%d')
|
|
468
|
-
dates2[-1] = tmpdate.max().strftime('%H:%M \n%Y-%m-%d')
|
|
469
|
-
ax2.set_xticks(np.arange(0,newdf.shape[0],6))
|
|
470
|
-
|
|
471
|
-
ax2.set_xticklabels(dates2[::6])
|
|
472
|
-
ax3.set_xlabel('时间(时:分,北京时)')
|
|
473
|
-
ax2.set_title('5分钟雨量(柱)、自动站累积雨量(红实线), 站号:%s,%s(%.2f°N,%.2f°E)'%(self.staid,self.sta_name,self.sta_lat,self.sta_lon),fontsize=12)
|
|
474
|
-
# plt.figtext(0.73,0.02,'国家气象中心-天气预报技术研发室制作',fontsize=10)
|
|
475
|
-
plt.savefig(self.outpath_pic + os.sep + self.outname_ref.replace('.nc','.%s'%self.pic_format),dpi=self.pic_dpi)#,dpi=600
|
|
476
|
-
print(self.outpath_pic + os.sep + self.outname_ref.replace('.nc','.%s'%self.pic_format) + ' saved!')
|
|
477
|
-
# plt.show()
|
|
478
|
-
plt.close()
|
|
479
|
-
return True
|
|
480
|
-
|
|
481
|
-
# 一键生成VPR数据和自动站数据,并绘制图形
|
|
482
|
-
def do_all(self,):
|
|
483
|
-
|
|
484
|
-
if not self.get_aws_data():
|
|
485
|
-
return False
|
|
486
|
-
if not self.get_tlogp_data():
|
|
487
|
-
return False
|
|
488
|
-
if not self.get_fmt_data():
|
|
489
|
-
return False
|
|
490
|
-
if not self.make_mosaic():
|
|
491
|
-
return False
|
|
492
|
-
if not self.make_vpr():
|
|
493
|
-
return False
|
|
494
|
-
if not self.draw_pic():
|
|
495
|
-
return False
|
|
496
|
-
|
|
497
|
-
if __name__ == "__main__":
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
freeze_support()
|
|
501
|
-
|
|
502
|
-
# sitelist=['G1174','G3522']
|
|
503
|
-
# for st in sitelist:
|
|
504
|
-
# _construct_vpr = CONSTRUCT_VPR(inifilepath='construct_aws_refvpr_mainprog_%s.ini'%st)
|
|
505
|
-
# _construct_vpr.do_all()
|
|
506
|
-
|
|
507
|
-
_construct_vpr = CONSTRUCT_VPR(inifilepath='metradar/construct_aws_refvpr_mainprog.ini')
|
|
508
|
-
_construct_vpr.do_all()
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|