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,538 @@
1
+ '''
2
+ 制作雷达拼图,多进程
3
+ 朱文剑
4
+ 2021
5
+
6
+ '''
7
+
8
+ # %%
9
+
10
+ import pyart
11
+ import os
12
+ import time
13
+ import pandas as pd
14
+ from datetime import datetime,timedelta
15
+ import numpy as np
16
+ from multiprocessing import Process,Pool
17
+ from mosaic_merge import mosaic_merge
18
+ import configparser
19
+ import warnings
20
+ import glob
21
+ warnings.filterwarnings('ignore')
22
+ import schedule
23
+ import threading
24
+ from decode_fmt_pyart import read_cnrad_fmt
25
+
26
+ class MAKE_RADAR_MOSAIC:
27
+
28
+ # sub function for reading config file
29
+ def ConfigFetchError(Exception):
30
+ pass
31
+
32
+ def _get_config_from_rcfile(self, rcfile):
33
+ """
34
+ Get configure information from xxx.ini file.
35
+ """
36
+ # print(os.getcwd())
37
+ # rc = os.getcwd() + os.sep + rcfile
38
+ rc = rcfile
39
+ if not os.path.exists(rc):
40
+ print('Config file: ' + rc + ' not exists!')
41
+ return None
42
+ try:
43
+ config = configparser.ConfigParser()
44
+ config.read(rc,encoding='UTF-8')
45
+ except IOError as e:
46
+ raise self.ConfigFetchError(str(e))
47
+ except Exception as e:
48
+ raise self.ConfigFetchError(str(e))
49
+
50
+ return config
51
+
52
+ def __init__(self,rcfile) -> None:
53
+ self.berror = False
54
+ if not os.path.exists(rcfile):
55
+ print(rcfile + ' not exists!')
56
+ self.berror = True
57
+ return None
58
+ config = self._get_config_from_rcfile(rcfile)
59
+ self.run_mode = config['RUN_MODE']['run_mode']
60
+
61
+ self.radar_mode = config['COMMON_SETTING']['radar_mode']
62
+ self.radar_sitesfile = config['COMMON_SETTING']['radar_sitesfile']
63
+
64
+ if not os.path.exists(self.radar_sitesfile):
65
+ print(self.radar_sitesfile + ' not exists!')
66
+ self.berror = True
67
+ return None
68
+
69
+ self.realtime_peroids = int(config['REAL_TIME']['realtime_peroids'])
70
+
71
+ self.center_lon = float(config['COMMON_SETTING']['center_lon'])
72
+ self.center_lat = float(config['COMMON_SETTING']['center_lat'])
73
+ self.mosaic_range = float(config['COMMON_SETTING']['mosaic_range'])
74
+ self.hori_reso = float(config['COMMON_SETTING']['hori_reso'])
75
+ self.verti_reso = float(config['COMMON_SETTING']['verti_reso'])
76
+ self.breplace = int(config['COMMON_SETTING']['breplace'])
77
+ self.bshow_debuginfo = int(config['COMMON_SETTING']['bshow_debuginfo'])
78
+
79
+ self.multi_levels = config['COMMON_SETTING']['multi_levels'].split(',')
80
+ self.multi_levels = [float(tt.strip(' ')) for tt in self.multi_levels]
81
+ self.mosaic_vars = config['COMMON_SETTING']['mosaic_vars'].split(',')
82
+ self.mosaic_vars = [tt.strip(' ') for tt in self.mosaic_vars]
83
+
84
+ if self.radar_mode == 'manul':
85
+ self.radars = config['COMMON_SETTING']['radars'].split(',')
86
+ self.radars = [tt.strip(' ') for tt in self.radars]
87
+ else:
88
+ pass
89
+ # 根据经纬度和半径,自动计算目标范围内的雷达站名
90
+ # 将km半径大致除以100,换算成°
91
+ minlon = self.center_lon - self.mosaic_range / 100.0
92
+ maxlon = self.center_lon + self.mosaic_range / 100.0
93
+ minlat = self.center_lat - self.mosaic_range / 100.0
94
+ maxlat = self.center_lat + self.mosaic_range / 100.0
95
+
96
+ # load radar site file
97
+
98
+ # 根据数字站号查找对应的中文名
99
+
100
+ frad = open(self.radar_sitesfile,'rt',encoding='UTF-8')
101
+
102
+ infos = frad.readlines()
103
+ radsite_num = {}
104
+ radname_gr2 = {}
105
+ staname_chn={}
106
+ radarlat={}
107
+ radarlon={}
108
+ radheight={}
109
+
110
+ for ss in infos:
111
+ tmps = ss.rstrip('\n').split('|')
112
+
113
+ curlon = float(tmps[4])
114
+ curlat = float(tmps[3])
115
+ if curlon > minlon and curlon < maxlon and curlat > minlat and curlat < maxlat:
116
+ radsite_num[tmps[0]] = tmps[2]
117
+ radname_gr2[tmps[2]] = tmps[0]
118
+ staname_chn[tmps[2]] = tmps[1]
119
+ radarlat[tmps[2]]=float(tmps[3])
120
+ radarlon[tmps[2]]=float(tmps[4])
121
+ radheight[tmps[2]]=float(tmps[5])
122
+ self.radars = list(radsite_num.keys())
123
+
124
+ self.input_path_realtime = config['REAL_TIME']['input_path_realtime']
125
+ self.output_path_realtime = config['REAL_TIME']['output_path_realtime']
126
+ self.input_path_archive = config['ARCHIVE']['input_path_archive']
127
+ self.output_path_archive = config['ARCHIVE']['output_path_archive']
128
+
129
+ self.starttime = config['ARCHIVE']['starttime']
130
+ self.endtime = config['ARCHIVE']['endtime']
131
+ self.tstep = int(config['ARCHIVE']['tstep'])
132
+
133
+ # check starttime and enttime
134
+ try:
135
+ st = datetime.strptime(self.starttime,'%Y%m%d%H%M')
136
+ except:
137
+ self.berror = True
138
+ print('starttime set error!')
139
+ return None
140
+
141
+ try:
142
+ et = datetime.strptime(self.endtime,'%Y%m%d%H%M')
143
+ except:
144
+ self.berror = True
145
+ print('endtime set error!')
146
+ return None
147
+
148
+
149
+
150
+ # check time step
151
+ if self.tstep < 0 or self.tstep > 60:
152
+ print('tstep set error, should between 0 and 60')
153
+ self.berror = True
154
+ return None
155
+
156
+ if (et - st).total_seconds() < self.tstep * 60:
157
+ print('seconds between endtime and starttime is less than tstep, error!')
158
+ self.berror = True
159
+ return None
160
+
161
+
162
+ pass
163
+
164
+
165
+ def make_mosaic(self, params):
166
+
167
+ '''
168
+ params={
169
+ # 原始数据路径
170
+ 'rootpath':rootpath,
171
+ # 输出数据路径
172
+ 'outpath': outpath,
173
+ # 参与拼图的雷达站点
174
+ 'radars': ['NJJS','HAJS','BBAH','MASR','HFAH','CZJS','TZJS'],
175
+ 'origin_latitude':center_lat, # 拼图的中心纬度
176
+ 'origin_longitude':center_lon, # 拼图的中心经度
177
+ 'mosaic_range':mosaic_range, # 拼图半径,km,其实是正方形
178
+ 'hor_reso':1, # 水平方向分辨率,km
179
+ 'ver_reso':0.5, # 垂直方向分辨率,km
180
+ 'bdebug':True,
181
+ 'timestr':timestr,
182
+ 'bot_z_lev':0.5, # 最底层所在高度
183
+ 'top_z_lev':16, # 最顶层所在高度
184
+ 'breplace':True,
185
+ 'outname': 'mosaic_%s.nc'%timestr
186
+ }
187
+ '''
188
+
189
+ rootpath=params['rootpath']
190
+ outpath=params['outpath']
191
+ radars=params['radars']
192
+ origin_latitude = params['origin_latitude']
193
+ origin_longitude = params['origin_longitude']
194
+ mr = params['mosaic_range']
195
+ hor_reso = params['hor_reso']
196
+ ver_reso = params['ver_reso']
197
+ bdebug = params['bdebug']
198
+ timestr = params['timestr']
199
+ outname = params['outname']
200
+ bot_z_lev = params['bot_z_lev']
201
+ top_z_lev = params['top_z_lev']
202
+ breplace = params['breplace']
203
+
204
+ # if timestr == '202307031912':
205
+ # pass
206
+ if not os.path.exists(outpath): os.makedirs(outpath)
207
+ # timestr = '201607190112'
208
+ if not breplace and os.path.exists(outpath + os.sep + outname):
209
+ print(outname + ' already exits!')
210
+ return False
211
+ curt = datetime.strptime(timestr,'%Y%m%d%H%M')
212
+ curt = curt.timestamp()
213
+ timeinfo=dict()
214
+ fileinfo=dict()
215
+ nvalidradars = 0
216
+ validradars=[]
217
+ for radar in radars:
218
+ curpath = rootpath + os.sep + radar
219
+ if not os.path.exists(curpath):
220
+ # print(curpath + ' not exists!')
221
+ # radars.remove(radar)
222
+ continue
223
+
224
+ curfiles = os.listdir(curpath)
225
+ if len(curfiles)==0:
226
+ print(curpath + ' file number = %d'%len(curfiles))
227
+ continue
228
+
229
+ validfiles = []
230
+ for ff in curfiles:
231
+ # if ff.find('ar2v') < 0:
232
+ if ff.find('_CAP_FMT.bin.bz2') < 0:
233
+ continue
234
+ else:
235
+ validfiles.append(ff)
236
+ curfiles = sorted(validfiles)
237
+ tmptime=[]
238
+ tmpfile=[]
239
+ for file in curfiles:
240
+ if file.find(radar) < 0:
241
+ print(file + ' not contain %s, so continue...'%radar)
242
+ # curfiles.remove(file)
243
+ continue
244
+
245
+ # cft = datetime.strptime(file[5:5+14],'%Y%m%d%H%M%S')
246
+ # Z_RADR_I_Z9090_20230703193348_O_DOR_SB_CAP_FMT.bin.bz2
247
+ # cft = datetime.strptime(file[5:13]+file[14:20],'%Y%m%d%H%M%S')
248
+ cft = datetime.strptime(file[15:29],'%Y%m%d%H%M%S')
249
+ tmptime.append(cft.timestamp())
250
+ tmpfile.append(curpath + os.sep + file)
251
+ if len(tmptime)==0:
252
+ continue
253
+ else:
254
+ timeinfo[radar]=tmptime
255
+ fileinfo[radar]=tmpfile
256
+
257
+ nvalidradars +=1
258
+ validradars.append(radar)
259
+ used_files = []
260
+ if nvalidradars == 0:
261
+ print('no valid files')
262
+ return False
263
+
264
+ for radar in validradars:
265
+ # print(radar)
266
+ tmpt = np.array(timeinfo[radar]) - curt
267
+ # try:
268
+ idx=list(abs(tmpt)).index(abs(tmpt).min())
269
+ # except:
270
+ # pass
271
+ if isinstance(idx,list):
272
+ idx = idx[0]
273
+ if abs(tmpt[idx]) > 240:
274
+ continue
275
+ used_files.append(fileinfo[radar][idx])
276
+ # assert isinstance(filenames,list)
277
+
278
+ if len(used_files)==0:
279
+ print('Error: len(used_files)==0')
280
+ return False
281
+ xgridnum = int(2*mr/hor_reso) + 1
282
+ ygridnum = int(2*mr/hor_reso) + 1
283
+ zgridnum = int((top_z_lev - bot_z_lev)/ver_reso) + 1
284
+ print('xgridnum = %d, ygridnum = %d, zgridnum = %d'%(xgridnum,ygridnum,zgridnum))
285
+ radars=[]
286
+ for filename in used_files:
287
+ try:
288
+ # radar = pyart.io.read_nexrad_archive(filename)
289
+ radar = read_cnrad_fmt(filename)
290
+ except:
291
+ print(filename + ' read error!')
292
+ continue
293
+ radars.append(radar)
294
+ print('add file %s'%filename)
295
+
296
+ sttime = time.time()
297
+ grid = pyart.map.grid_from_radars(
298
+ tuple(radars),
299
+ grid_origin = [origin_latitude,origin_longitude],
300
+ grid_shape=(zgridnum, ygridnum, xgridnum),
301
+ grid_limits=((bot_z_lev*1000, top_z_lev*1000), (-1.0*mr*1000, 1.0*mr*1000), (-1.0*mr*1000, 1.0*mr*1000)),
302
+ fields=['reflectivity',])#'differential_reflectivity','differential_phase'
303
+
304
+ edtime = time.time()
305
+ if bdebug:
306
+ print('grid over! cost time = %d seconds'%(int(edtime - sttime)))
307
+
308
+
309
+ outref = grid.fields['reflectivity']['data']
310
+ # prepare for netcdf output
311
+ # outref = outref *2 + 64
312
+ # grid.fields['reflectivity']['data'] = outref
313
+ # grid.fields['reflectivity']['valid_max'] = np.array(grid.fields['reflectivity']['valid_max'] * 2 + 64).astype(np.uint8)
314
+ # grid.fields['reflectivity']['valid_min'] = np.array(grid.fields['reflectivity']['valid_min'] * 2 + 64).astype(np.uint8)
315
+
316
+ grid.fields['reflectivity']['data'] = outref
317
+ grid.fields['reflectivity']['valid_max'] = np.array(grid.fields['reflectivity']['valid_max'])
318
+ grid.fields['reflectivity']['valid_min'] = np.array(grid.fields['reflectivity']['valid_min'])
319
+
320
+ # write to netcdf
321
+ # gx = grid.to_xarray()
322
+ # gx.reflectivity.data=gx.reflectivity.astype(np.uint8)
323
+ # gx = gx.drop_vars('ROI')
324
+ # cref = np.nanmax(gx.reflectivity.data[0,:,:,:],axis=0)
325
+ # # 增加变量到Dataset
326
+ # gx["cref"]=(['y', 'x'],cref,{'scale':2,'offset':64,'decode':'dBZ = (cref-64)/2'})
327
+ # # gx = gx.drop_vars('reflectivity')
328
+ # gx.to_netcdf(outpath + os.sep + outname)
329
+
330
+ pyart.io.write_grid(outpath + os.sep + outname ,grid)
331
+
332
+ print(outpath + os.sep + outname + ' done!')
333
+
334
+ def do_realtime(self,):
335
+ if os.path.exists('file.lock'):
336
+ print('do_realtime still running')
337
+ return False
338
+
339
+ print('进入 do_realtime')
340
+
341
+ # 创建锁文件,防止程序重复运行
342
+ lockfile = open('file.lock','wt')
343
+ lockfile.write(datetime.utcnow().strftime('%Y%m%d%H%M%S'))
344
+ lockfile.close()
345
+
346
+ rootpath = self.input_path_realtime
347
+ outpath = self.output_path_realtime
348
+ radars = self.radars
349
+ center_lat = self.center_lat
350
+ center_lon = self.center_lon
351
+ mosaic_range = self.mosaic_range
352
+ hor_reso = self.hori_reso
353
+ ver_reso = self.verti_reso
354
+ bshow_debug = self.bshow_debuginfo
355
+ breplace = self.breplace
356
+ levels = self.multi_levels
357
+
358
+ allparams = []
359
+ ct = datetime.utcnow()
360
+ newct = ct - timedelta(minutes= ct.minute % 6 )
361
+ timestr = newct.strftime('%Y%m%d%H%M')
362
+ print('processing : ' + timestr)
363
+
364
+ alloutfiles=[]
365
+ mergename = outpath + os.sep + 'mosaic_%s.nc'%timestr
366
+ if not breplace and os.path.exists(mergename):
367
+ print(mergename + ' already exists!')
368
+ return True
369
+
370
+ for nn in range(len(levels)-1):
371
+
372
+ outname = 'mosaic_%s_%d_tmp.nc'%(timestr,nn+1)
373
+ # 分为多个进程,每个进程计算一段高度上的拼图,最后再进行拼接
374
+ params={
375
+ # 原始数据路径
376
+ 'rootpath':rootpath,
377
+ # 输出数据路径
378
+ 'outpath': outpath,
379
+ # 参与拼图的雷达站点
380
+ 'radars':radars,
381
+ 'origin_latitude':center_lat, # 拼图的中心纬度
382
+ 'origin_longitude':center_lon, # 拼图的中心经度
383
+ 'mosaic_range':mosaic_range, # 拼图半径,km,其实是正方形
384
+ 'hor_reso':hor_reso, # 水平方向分辨率,km
385
+ 'ver_reso':ver_reso, # 垂直方向分辨率,km
386
+ 'bdebug':bshow_debug,
387
+ 'timestr':timestr, # 时间戳,程序按照这个时间来匹配数据
388
+ 'bot_z_lev':levels[nn] + ver_reso, # 最底层所在高度
389
+ 'top_z_lev':levels[nn+1], # 最顶层所在高度
390
+ 'breplace':breplace,
391
+ 'outname':outname,
392
+ }
393
+
394
+ alloutfiles.append(outpath + os.sep + outname)
395
+ allparams.append(params)
396
+
397
+ MAXP=len(levels)-1
398
+ pools = Pool(MAXP)
399
+
400
+ pools.map(self.make_mosaic, allparams)
401
+ pools.close()
402
+ pools.join()
403
+
404
+ # 对数据进行拼接
405
+
406
+ newgrid = mosaic_merge(files = alloutfiles)
407
+ # write to file
408
+ if newgrid is not None:
409
+ newgrid.write(mergename)
410
+ print(mergename + ' saved!')
411
+ # time.sleep(2)
412
+
413
+ else:
414
+ print('merge error!')
415
+ # delete temp files
416
+ files = glob.glob(outpath + os.sep + '*tmp.nc')
417
+ if len(files) >0:
418
+ for file in files:
419
+ os.remove(file)
420
+
421
+ # 删除锁文件,允许程序运行
422
+ if os.path.exists('file.lock'): os.remove('file.lock')
423
+
424
+
425
+ def do_archive(self,):
426
+
427
+ st = datetime.strptime(self.starttime,'%Y%m%d%H%M')
428
+ et = datetime.strptime(self.endtime,'%Y%m%d%H%M')
429
+ periods = int(((et - st).total_seconds() / 60)/self.tstep)+1
430
+ print('periods = %d'%periods)
431
+ dt = pd.date_range(st,freq='%dmin'%self.tstep,periods=periods)
432
+ dt = pd.to_datetime(dt)
433
+ alltimes=[tt.strftime('%Y%m%d%H%M') for tt in dt]
434
+
435
+
436
+
437
+ # radars = self.radars
438
+ # center_lat = _make_mosaic.center_lat
439
+ # center_lon = _make_mosaic.center_lon
440
+ # mosaic_range = _make_mosaic.mosaic_range
441
+ # hor_reso = _make_mosaic.hori_reso
442
+ # ver_reso = _make_mosaic.verti_reso
443
+ # bshow_debug = self.bshow_debuginfo
444
+ # breplace = _make_mosaic.breplace
445
+ # levels = self.multi_levels
446
+
447
+ # levels 高度层 单位KM
448
+ # levels = [0, 5, 9, 12, 16]
449
+ # levels = [0, 7, 10, 13, 16, 20] 82s
450
+ # levels = [0, 7, 10, 13, 16, 20]
451
+ # MAXP = int(cpu_count()*0.2)
452
+
453
+
454
+ for timestr in alltimes:
455
+ allparams = []
456
+ print('processing : ' + timestr)
457
+
458
+ alloutfiles=[]
459
+ rootpath = self.input_path_archive + os.sep + timestr[0:4] + os.sep + timestr[0:8]
460
+ outpath = self.output_path_archive
461
+
462
+ if not os.path.exists(outpath):
463
+ os.makedirs(outpath)
464
+ mergename = outpath + os.sep + 'mosaic_%s.nc'%timestr
465
+ if not self.breplace and os.path.exists(mergename):
466
+ print(mergename + ' already exists!')
467
+ continue
468
+
469
+ for nn in range(len(self.multi_levels)-1):
470
+
471
+ outname = 'mosaic_%s_%d_tmp.nc'%(timestr,nn+1)
472
+ # 分为多个进程,每个进程计算一段高度上的拼图,最后再进行拼接
473
+ params={
474
+ # 原始数据路径
475
+ 'rootpath':rootpath,
476
+ # 输出数据路径
477
+ 'outpath': outpath,
478
+ # 参与拼图的雷达站点
479
+ 'radars':self.radars,
480
+ 'origin_latitude':self.center_lat, # 拼图的中心纬度
481
+ 'origin_longitude':self.center_lon, # 拼图的中心经度
482
+ 'mosaic_range':self.mosaic_range, # 拼图半径,km,其实是正方形
483
+ 'hor_reso':self.hori_reso, # 水平方向分辨率,km
484
+ 'ver_reso':self.verti_reso, # 垂直方向分辨率,km
485
+ 'bdebug':self.bshow_debuginfo,
486
+ 'timestr':timestr, # 时间戳,程序按照这个时间来匹配数据
487
+ 'bot_z_lev':self.multi_levels[nn] + nn*self.verti_reso, # 最底层所在高度
488
+ 'top_z_lev':self.multi_levels[nn+1], # 最顶层所在高度
489
+ 'breplace':self.breplace,
490
+ 'outname':outname,
491
+ }
492
+
493
+ alloutfiles.append(outpath + os.sep + outname)
494
+ allparams.append(params)
495
+
496
+ MAXP=len(self.multi_levels)-1
497
+ pools = Pool(MAXP)
498
+
499
+ pools.map(self.make_mosaic, allparams)
500
+ pools.close()
501
+ pools.join()
502
+
503
+ # 对数据进行拼接
504
+
505
+ newgrid = mosaic_merge(files = alloutfiles)
506
+ if newgrid is not None:
507
+ # write to file
508
+ newgrid.write(mergename)
509
+
510
+ print(mergename + ' saved!')
511
+ else:
512
+ print('merge error!')
513
+ # time.sleep(2)
514
+ # delete temp files
515
+ files = glob.glob(outpath + os.sep + '*tmp.nc')
516
+ if len(files) >0:
517
+ for file in files:
518
+ os.remove(file)
519
+
520
+ def run_threaded(job_func):
521
+ job_thread = threading.Thread(target=job_func)
522
+ job_thread.start()
523
+
524
+ if __name__ == "__main__":
525
+
526
+ print('starting mosaic program......')
527
+
528
+ _make_mosaic = MAKE_RADAR_MOSAIC('make_mosaic_mp_archive.ini')
529
+
530
+ if not _make_mosaic.berror:
531
+ if _make_mosaic.run_mode == 'archive':
532
+ _make_mosaic.do_archive()
533
+ else:
534
+ print('run mode is not archive!')
535
+
536
+
537
+
538
+ # %%
@@ -0,0 +1,64 @@
1
+ '''
2
+ 将不同层次的mosacdata stack在一起
3
+ ZhuWJ
4
+
5
+ '''
6
+
7
+ # %%
8
+ import pyart
9
+ import os
10
+ import numpy as np
11
+
12
+
13
+ # 将多层的临时文件在高度维度上进行拼接
14
+ def mosaic_merge(files:list):
15
+
16
+ grids = []
17
+ for file in files:
18
+ if not os.path.exists(file):
19
+ print(file + ' not exists!')
20
+ return None
21
+ try:
22
+ tmpgrid = pyart.io.read_grid(file)
23
+ grids.append(tmpgrid)
24
+ print(tmpgrid.nz,tmpgrid.ny,tmpgrid.nx)
25
+ except:
26
+ print(file + ' load error!')
27
+ return None
28
+
29
+
30
+ # newz = list(grid1.z['data']) + list(grid2.z['data'])
31
+ newz = []
32
+ for nn in range(len(grids)):
33
+ for val in grids[nn].z['data']:
34
+ newz.append(val)
35
+
36
+ # trans list to mask array
37
+ newz = np.ma.MaskedArray(newz)
38
+
39
+ # 对数据进行垂直方向拼接
40
+ newgrid = pyart.io.read_grid(files[0])
41
+ newgrid.z['data'] = newz
42
+ newgrid.nz = len(newz)
43
+
44
+ # 对所有的field都要进行拼接
45
+ for field in newgrid.fields.keys():
46
+ newdata = np.ma.zeros((newgrid.nz,newgrid.ny,newgrid.nx),dtype='float32')
47
+ newdata[:grids[0].nz,:,:] = grids[0].fields[field]['data']
48
+ curidx=grids[0].nz
49
+ for nn in range(len(grids)-1):
50
+ newdata[curidx:curidx+grids[nn+1].nz,:,:] = grids[nn+1].fields[field]['data']
51
+ curidx +=grids[nn+1].nz
52
+
53
+ newgrid.fields[field]['data'] = np.ma.MaskedArray(newdata)
54
+
55
+
56
+ return newgrid
57
+
58
+ # 如果拼接成功,那么可以调用grid3.to_xarray()来检验,看返回是否成功
59
+ # grid3.to_xarray()
60
+
61
+
62
+ if __name__ == "__main__":
63
+
64
+ pass