Skip to content

Commit 8c98f43

Browse files
authored
Rewrote readers & fix bugs on plotter
1 parent 7b66ff6 commit 8c98f43

File tree

7 files changed

+158
-153
lines changed

7 files changed

+158
-153
lines changed

HY_Plotter/hy_plotter.py

+53-50
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,33 @@ def stepcal(lonmax, lonmin, res, num=15, ip=1):
3636
totalpt = (lonmax - lonmin) / res * ip
3737
return int(totalpt / num)
3838

39-
def grid(route, fname, georange, sfname, band, lonlatstep=5, res=0.125, num=15, ip=1, full_res=-1, **kwargs):
39+
def grid(route, fname, georange, sfname, band, lonlatstep=5, num=15, ip=1, full_res=-1, **kwargs):
4040
config = kwargs["config"]
4141

42-
lats, lons, data_spd, data_dir, data_time, sate_name, res = rgrib.get_data(route + fname, band)
42+
lats, lons, data_spd, data_dir, data_time, sate_name, res = rgrib.get_data(route + fname, band, georange)
4343

4444
# transfroming resolution into degree if it's string type
4545
_res_temp = res
4646
if isinstance(_res_temp, str):
4747
if "°" in _res_temp:
4848
_res_temp = float(_res_temp[:-1])
49+
res = f"{_res_temp * 100}"
50+
if res.endswith(".0"):
51+
res = res[:-2] + "KM"
52+
else:
53+
res += "KM"
4954
elif "KM" in _res_temp.upper():
5055
_res_temp = float(_res_temp[:-2]) / 100
5156
else:
5257
_res_temp = float(_res_temp)
58+
if "." in res:
59+
res = f"{_res_temp * 100}"
60+
if res.endswith(".0"):
61+
res = res[:-2] + "KM"
62+
else:
63+
res += "KM"
64+
else:
65+
res += "KM"
5366

5467
if isinstance(georange, tuple):
5568
# get range parameter
@@ -93,55 +106,29 @@ def grid(route, fname, georange, sfname, band, lonlatstep=5, res=0.125, num=15,
93106
ax.patch.set_facecolor("#000000")
94107

95108
# process data's valid time (latest)
96-
if sate_name == "CFOSAT":
97-
data_time = datetime.datetime.strptime(data_time, "%Y-%m-%dT%H:%M:%SZ").strftime('%Y/%m/%d %H%MZ')
109+
if "CFOSAT" in sate_name:
110+
try:
111+
data_time = datetime.datetime.strptime(data_time, "%Y-%m-%dT%H:%M:%SZ").strftime('%Y/%m/%d %H%MZ')
112+
except Exception:
113+
data_time = datetime.datetime.strptime(data_time, "%Y-%m-%d %H:%M:%SZ").strftime('%Y/%m/%d %H%MZ')
114+
elif "HY-2" in sate_name:
115+
try:
116+
data_time = datetime.datetime.strptime(data_time, "%Y%m%dT%H:%M:%S").strftime('%Y/%m/%d %H%MZ')
117+
except Exception:
118+
data_time = datetime.datetime.strptime(data_time, "%Y%m%dT%H:%M:%S.%f").strftime('%Y/%m/%d %H%MZ')
119+
elif "FY-3E" in sate_name:
120+
try:
121+
data_time = datetime.datetime.strptime(data_time, "%Y%m%d%H%M").strftime('%Y/%m/%d %H%MZ')
122+
except Exception:
123+
data_time = datetime.datetime.strptime(data_time, "%Y%m%d %H:%M:%S.%f").strftime('%Y/%m/%d %H%MZ')
98124
else:
99-
if "HY" in sate_name:
100-
try:
101-
data_time = datetime.datetime.strptime(data_time, "%Y%m%dT%H:%M:%S").strftime('%Y/%m/%d %H%MZ')
102-
except Exception:
103-
data_time = datetime.datetime.strptime(data_time, "%Y%m%dT%H:%M:%S.%f").strftime('%Y/%m/%d %H%MZ')
104-
elif "FY-3E" in sate_name:
105-
try:
106-
data_time = datetime.datetime.strptime(data_time, "%Y%m%d%H%M").strftime('%Y/%m/%d %H%MZ')
107-
except Exception:
108-
data_time = datetime.datetime.strptime(data_time, "%Y%m%d %H:%M:%S.%f").strftime('%Y/%m/%d %H%MZ')
109-
else:
110-
try:
111-
data_time = datetime.datetime.strptime(data_time, "%Y%m%dT%H:%M:%S").strftime('%Y/%m/%d %H%MZ')
112-
except Exception:
113-
try:
114-
data_time = datetime.datetime.strptime(data_time, "%Y%m%dT%H:%M:%S.%f").strftime('%Y/%m/%d %H%MZ')
115-
except Exception:
116-
try:
117-
data_time = datetime.datetime.strptime(data_time, "%Y-%m-%dT%H:%M:%SZ").strftime('%Y/%m/%d %H%MZ')
118-
except Exception:
119-
try:
120-
data_time = datetime.datetime.strptime(data_time, "%Y-%m-%dT%H:%M:%S.%fZ").strftime('%Y/%m/%d %H%MZ')
121-
except Exception:
122-
try:
123-
data_time = datetime.datetime.strptime(data_time, "%Y-%m-%dT%H:%M:%SZ").strftime('%Y/%m/%d %H%MZ')
124-
except Exception:
125-
data_time = datetime.datetime.strptime(data_time, "%Y-%m-%d %H:%M:%S").strftime('%Y/%m/%d %H%MZ')
125+
try:
126+
data_time = datetime.datetime.strptime(data_time, "%Y%m%dT%H:%M:%S").strftime('%Y/%m/%d %H%MZ')
127+
except Exception:
128+
data_time = datetime.datetime.strptime(data_time, "%Y-%m-%d %H:%M:%S").strftime('%Y/%m/%d %H%MZ')
126129

127130
print("...PLOTING...")
128131

129-
'''
130-
# get area's max wind
131-
# You can delete these codes if you do not want to show the max wind
132-
'''
133-
dspd = data_spd[(lons<=lonmax)&(lons>=lonmin)&(lats<=latmax)&(lats>=latmin)]
134-
if len(dspd) > 0 and not isinstance(dspd.max(), np.ma.core.MaskedConstant):
135-
damax = round(dspd.max(), 1)
136-
else:
137-
damax = "0.0"
138-
139-
# add title at the top of figure
140-
text = f'{sate_name} {res} Wind (barbs) [kt] (Generated by @Shuitai)\nValid Time: {data_time}'
141-
ax.set_title(text, loc='left', fontsize=5)
142-
text = f'Max. Wind: {damax}kt'
143-
ax.set_title(text, loc='right', fontsize=4)
144-
145132
# plot brabs with colormap and color-bar
146133
cmap, vmin, vmax = cm.get_colormap("wind")
147134

@@ -190,6 +177,22 @@ def grid(route, fname, georange, sfname, band, lonlatstep=5, res=0.125, num=15,
190177
cb.ax.tick_params(labelsize=4, length=0)
191178
cb.outline.set_linewidth(0.3)
192179

180+
'''
181+
# get area's max wind
182+
# You can delete these codes if you do not want to show the max wind
183+
'''
184+
dspd = data_spd[(lons<=lonmax)&(lons>=lonmin)&(lats<=latmax)&(lats>=latmin)]
185+
if len(dspd) > 0 and not isinstance(dspd.max(), np.ma.core.MaskedConstant):
186+
damax = round(dspd.max(), 1)
187+
else:
188+
damax = "0.0"
189+
190+
# add title at the top of figure
191+
text = f'{sate_name} {res} Wind (barbs) [kt] (Generated by @Shuitai)\nValid Time: {data_time}'
192+
ax.set_title(text, loc='left', fontsize=5)
193+
text = f'Max. Wind: {damax}kt'
194+
ax.set_title(text, loc='right', fontsize=4)
195+
193196
# add coastlines
194197
ax.add_feature(
195198
cfeature.COASTLINE.with_scale("10m"),
@@ -219,8 +222,8 @@ def grid(route, fname, georange, sfname, band, lonlatstep=5, res=0.125, num=15,
219222
gl.bottom_labels = True
220223
gl.right_labels = False
221224
gl.left_labels = True
222-
gl.xpadding = 2.5
223-
gl.ypadding = 2.5
225+
gl.xpadding = 3
226+
gl.ypadding = 3
224227
gl.xlabel_style = {'size': 4, 'color': 'k', 'ha': 'center'}
225228
gl.ylabel_style = {'size': 4, 'color': 'k', 'va': 'center'}
226229
plt.rcParams['axes.unicode_minus'] = False
@@ -274,4 +277,4 @@ def grid(route, fname, georange, sfname, band, lonlatstep=5, res=0.125, num=15,
274277
save_name = "" # fill in any name what you like
275278

276279
# finish loading config, start gird
277-
grid(route, file, georange, save_name, band, res=0.125, num=20, ip=1, lonlatstep=step, full_res=f_res, config=config)
280+
grid(route, file, georange, save_name, band, num=15, ip=1, lonlatstep=step, full_res=f_res, config=config)

HY_Plotter/windReader/reader/__init__.py

+3-6
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,7 @@ def load_reader(reader_name):
1010

1111
def test_reader(reader_name, fname):
1212
try:
13-
lats, lons, data_spd, data_dir, data_time, sate_name, res = WIND_READER_CONFIG[reader_name].extract(fname)
14-
if res == "":
15-
return False
16-
else:
17-
return True
18-
except Exception:
13+
test_result = WIND_READER_CONFIG[reader_name].extract(fname, test=True)
14+
return test_result
15+
except Exception as e:
1916
return False

HY_Plotter/windReader/reader/ascat.py

+21-3
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,42 @@
44

55
class ASCAT(object):
66

7-
def extract(fname):
7+
def extract(fname, georange=(), test=False):
88
try:
99
init = netCDF4.Dataset(fname)
1010
except Exception:
11+
if test:
12+
return False
1113
lats, lons, data_spd, data_dir, data_time, sate_name, res = [], [], [], [], "", "", ""
1214
return lats, lons, data_spd, data_dir, data_time, sate_name, res
1315
if "ASCAT" in init.title:
16+
if test:
17+
return True
18+
if georange == ():
19+
lats, lons, data_spd, data_dir, data_time, sate_name, res = [], [], [], [], "", "", ""
20+
return lats, lons, data_spd, data_dir, data_time, sate_name, res
1421
# get values
1522
lons, lats = init.variables["lon"][:], init.variables["lat"][:]
1623
data_spd, data_dir = init.variables["wind_speed"][:], init.variables["wind_dir"][:]
17-
data_spd, data_dir = data_spd[:], data_dir[:]
18-
data_time = f"{init.stop_date} {init.stop_time}"
24+
row_time = init.variables["time"][:]
1925
sate_name = init.source + " Level 2"
2026
res = init.pixel_size_on_horizontal.replace(".0", "").replace(" ","")
2127
# process values
2228
lons.fill_value = lats.fill_value = data_spd.fill_value = data_dir.fill_value = -32768
2329
data_spd = data_spd / 0.514
2430
lons[lons < 0] += 360
31+
latmin, latmax, lonmin, lonmax = georange
32+
lon_mean = (lonmin + lonmax) / 2
33+
loc = ()
34+
for ilon, lon in np.ndenumerate(lons):
35+
if abs(lon_mean - lon) <= 0.25:
36+
loc = ilon
37+
break
38+
loc_time = row_time[loc[0],loc[1]]
39+
from datetime import date, datetime, timedelta
40+
_time = date(1990, 1, 1)
41+
_time += timedelta(seconds=loc_time)
42+
data_time = _time.strftime('%Y%m%dT%H:%M:%S')
2543
else:
2644
lats, lons, data_spd, data_dir, data_time, sate_name, res = [], [], [], [], "", "", ""
2745
return lats, lons, data_spd, data_dir, data_time, sate_name, res

HY_Plotter/windReader/reader/cfosat.py

+21-8
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,40 @@
44

55
class CFOSAT(object):
66

7-
def extract(fname):
7+
def extract(fname, georange=(), test=False):
88
try:
99
init = netCDF4.Dataset(fname)
1010
except Exception:
11+
if test:
12+
return False
1113
lats, lons, data_spd, data_dir, data_time, sate_name, res = [], [], [], [], "", "", ""
1214
return lats, lons, data_spd, data_dir, data_time, sate_name, res
13-
1415
if init.platform == "CFOSAT":
16+
if test:
17+
return True
18+
if georange == ():
19+
lats, lons, data_spd, data_dir, data_time, sate_name, res = [], [], [], [], "", "", ""
20+
return lats, lons, data_spd, data_dir, data_time, sate_name, res
1521
# get values
1622
lons, lats = init.variables["wvc_lon"][:], init.variables["wvc_lat"][:]
1723
data_spd, data_dir = init.variables["wind_speed_selection"][:], init.variables["wind_dir_selection"][:]
18-
# data_spd, data_dir = data_spd[:,:,band_index], data_dir[:,:,band_index]
19-
data_time = init.time_coverage_end
24+
row_time = init.variables["row_time"][:]
2025
sate_name = f"{init.platform} Scatterometer Level 2B"
21-
if init.dimensions["numrows"].size == 3248:
22-
res = "0.125°"
23-
else:
24-
res = "0.25°"
26+
res = f"{init.geospatial_lon_resolution}"
2527
# process values
2628
data_spd = data_spd / 0.514
2729
lons[lons < 0] += 360
30+
latmin, latmax, lonmin, lonmax = georange
31+
lon_mean = (lonmin + lonmax) / 2
32+
loc = ()
33+
for ilon, lon in np.ndenumerate(lons):
34+
if abs(lon_mean - lon) <= 0.25:
35+
loc = ilon
36+
break
37+
loc_time = row_time[loc[0]]
38+
data_time = ''
39+
for t in loc_time:
40+
data_time += t.decode('utf-8')
2841
else:
2942
lats, lons, data_spd, data_dir, data_time, sate_name, res = [], [], [], [], "", "", ""
3043
return lats, lons, data_spd, data_dir, data_time, sate_name, res

HY_Plotter/windReader/reader/fy3e.py

+11-5
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,27 @@
44

55
class FY3E(object):
66

7-
def extract(fname, band="C_band"):
7+
def extract(fname, georange=(), band="C_band", test=False):
88
try:
99
init = h5py.File(fname, "r")
1010
except Exception:
11+
if test:
12+
return False
1113
lats, lons, data_spd, data_dir, data_time, sate_name, res = [], [], [], [], "", "", ""
1214
return lats, lons, data_spd, data_dir, data_time, sate_name, res
13-
1415
if "FY3E" in str(init.attrs["File Name"]):
16+
if test:
17+
return True
18+
if georange == ():
19+
lats, lons, data_spd, data_dir, data_time, sate_name, res = [], [], [], [], "", "", ""
20+
return lats, lons, data_spd, data_dir, data_time, sate_name, res
1521
# get values
16-
fns = str(init.attrs["File Name"]).split("_")
22+
fns = init.attrs["File Name"].decode('utf-8').split("_")
1723
lons, lats = init[band]["wvc_lon"][:], init[band]["wvc_lat"][:]
1824
data_spd, data_dir = init[band]["wind_speed_selected"][:], init[band]["wind_dir_selected"][:]
1925
data_time = fns[7] + fns[8]
20-
sate_name = str(init.attrs["Satellite Name"]).replace("b","").replace("'","") \
21-
+ " " + str(init.attrs["Sensor Name"]).replace("b","").replace("'","")
26+
sate_name = init.attrs["Satellite Name"].decode('utf-8') \
27+
+ " " + init.attrs["Sensor Name"].decode('utf-8')
2228
if band == "C_band":
2329
res = "20KM"
2430
elif band == "Ku_band":

HY_Plotter/windReader/reader/hy.py

+25-9
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,43 @@
44

55
class HY(object):
66

7-
def extract(fname, band_index=0):
7+
def extract(fname, georange=(), test=False):
88
try:
99
init = h5py.File(fname, "r")
1010
except Exception:
11+
if test:
12+
return False
1113
lats, lons, data_spd, data_dir, data_time, sate_name, res = [], [], [], [], "", "", ""
1214
return lats, lons, data_spd, data_dir, data_time, sate_name, res
13-
14-
if "HY" in str(init.attrs["Platform_ShortName"][-1]):
15+
if "HY-2" in init.attrs["Platform_ShortName"][-1].decode('utf-8'):
16+
if test:
17+
return True
18+
if georange == ():
19+
lats, lons, data_spd, data_dir, data_time, sate_name, res = [], [], [], [], "", "", ""
20+
return lats, lons, data_spd, data_dir, data_time, sate_name, res
1521
# get values
1622
fns = fname.split("_", -1)
1723
lons, lats = init["wvc_lon"][:], init["wvc_lat"][:]
1824
data_spd, data_dir = init["wind_speed_selection"][:], init["wind_dir_selection"][:]
19-
data_spd, data_dir = data_spd[:,:,band_index], data_dir[:,:,band_index]
20-
data_time = str(init["wvc_row_time"][:][init["wvc_row_time"][:] != b''][-1]).replace("b","").replace("'","").strip()
21-
sate_name = str(init.attrs["Platform_ShortName"][-1]).replace("b","").replace("'","").strip() + " Scatterometer Level 2B"
22-
res = "0.25°"
25+
row_time = init["wvc_row_time"][:]
26+
sate_name = init.attrs["Platform_ShortName"][-1].decode('utf-8').strip() \
27+
+ " Scatterometer Level 2B"
28+
res = "25KM"
2329
# process values
24-
lons, lats = np.ma.array(lons, mask=lons == 1.7e+38, fill_value=-32768), np.ma.array(lats, mask=lats == 1.7e+38, fill_value=-32768)
25-
data_spd, data_dir = np.ma.array(data_spd, mask=data_spd == -32767, fill_value=-32768), np.ma.array(data_dir, mask=data_dir == -32767, fill_value=-32768)
30+
lons = np.ma.array(lons, mask=lons == 1.7e+38, fill_value=-32768)
31+
lats = np.ma.array(lats, mask=lats == 1.7e+38, fill_value=-32768)
32+
data_spd = np.ma.array(data_spd, mask=data_spd == -32767, fill_value=-32768)
33+
data_dir = np.ma.array(data_dir, mask=data_dir == -32767, fill_value=-32768)
2634
data_spd, data_dir = data_spd / 100 / 0.514, data_dir / 10
2735
lons[lons < 0] += 360
36+
latmin, latmax, lonmin, lonmax = georange
37+
lon_mean = (lonmin + lonmax) / 2
38+
loc = ()
39+
for ilon, lon in np.ndenumerate(lons):
40+
if abs(lon_mean - lon) <= 0.25:
41+
loc = ilon[0]
42+
break
43+
data_time = row_time[loc].decode('utf-8').strip()
2844
else:
2945
lats, lons, data_spd, data_dir, data_time, sate_name, res = [], [], [], [], "", "", ""
3046
return lats, lons, data_spd, data_dir, data_time, sate_name, res

0 commit comments

Comments
 (0)