Browse Source

Some scale fix

master
FedorSarafanov 2 days ago
parent
commit
2923202637
  1. BIN
      2025-06-01.gif
  2. 19
      make_gif.py
  3. 39
      msg_converter.py

BIN
2025-06-01.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 MiB

19
make_gif.py

@ -40,16 +40,18 @@ def create_gif(npz_path, output_path=None): @@ -40,16 +40,18 @@ def create_gif(npz_path, output_path=None):
# Максимумы по z
dbz_max = np.nanmax(data['dbz'], axis=3) # (144, 100, 100)
dbzd_max = np.nanmax(data['dbzd'], axis=3) # (144, 100, 100)
doppler_max = np.nanmax(data['doppler'], axis=3) # (144, 100, 100)
meteo = data['meteo'] # (144, 100, 100)
# Срезы по высоте
doppler_5km = data['doppler'][:, :, :, 5] # (144, 100, 100)
# Диапазоны для colorbar
vmin_dbz = np.nanpercentile(dbz_max, 1)
vmax_dbz = np.nanpercentile(dbz_max, 99)
vmin_dbzd = np.nanpercentile(dbzd_max, 1)
vmax_dbzd = np.nanpercentile(dbzd_max, 99)
vmin_doppler = np.nanpercentile(doppler_max, 1)
vmax_doppler = np.nanpercentile(doppler_max, 99)
vmin_doppler = np.nanpercentile(doppler_5km, 1)
vmax_doppler = np.nanpercentile(doppler_5km, 99)
vmin_meteo = np.nanmin(meteo)
vmax_meteo = np.nanmax(meteo)
@ -67,9 +69,12 @@ def create_gif(npz_path, output_path=None): @@ -67,9 +69,12 @@ def create_gif(npz_path, output_path=None):
axes[0, 1].set_title('max(dBzD)')
axes[0, 1].axis('off')
plt.colorbar(im2, ax=axes[0, 1], fraction=0.046)
mod_seismic = plt.cm.seismic.copy()
mod_seismic.set_bad(color='black')
im3 = axes[1, 0].imshow(doppler_max[0], cmap='seismic', vmin=vmin_doppler, vmax=vmax_doppler)
axes[1, 0].set_title('max(Doppler)')
im3 = axes[1, 0].imshow(doppler_5km[0], cmap=mod_seismic, vmin=vmin_doppler, vmax=vmax_doppler)
axes[1, 0].set_title('Doppler [5 km]')
axes[1, 0].axis('off')
plt.colorbar(im3, ax=axes[1, 0], fraction=0.046)
@ -86,7 +91,7 @@ def create_gif(npz_path, output_path=None): @@ -86,7 +91,7 @@ def create_gif(npz_path, output_path=None):
"""Обновление кадра"""
im1.set_array(dbz_max[frame])
im2.set_array(dbzd_max[frame])
im3.set_array(doppler_max[frame])
im3.set_array(doppler_5km[frame])
im4.set_array(meteo[frame])
if data['times'] is not None:
@ -107,7 +112,7 @@ def create_gif(npz_path, output_path=None): @@ -107,7 +112,7 @@ def create_gif(npz_path, output_path=None):
print("Создание анимации...")
anim = FuncAnimation(fig, update, frames=n_frames, interval=100, blit=True)
print(f"Сохранение GIF: {output_path}")
print(f"Сохранение GIF: {output_path}\n")
writer = PillowWriter(fps=10)
anim.save(output_path, writer=writer)

39
msg_converter.py

@ -55,8 +55,8 @@ DESCRIPTORS = { @@ -55,8 +55,8 @@ DESCRIPTORS = {
"0 31 002": {"bits": 16, "scale": 0, "offset": 0, "type": "UINT","name": "EXTENDED DELAYED DESCRIPT.REPLIC.FACTOR"},
"0 31 012": {"bits": 16, "scale": 0, "offset": 0, "type": "UINT","name": "EXT.DEL.DESCRIPT.AND DATA REPETIT.FACTOR"},
"0 21 001": {"bits": 7, "scale": 0, "offset": -64, "type": "UINT", "name": "HORIZONTAL REFLECTIVITY"},
"0 21 003": {"bits": 7, "scale": 1, "offset": -5, "type": "UINT", "name": "DIFFERENTIAL REFLECTIVITY"},
"0 21 014": {"bits": 13, "scale": 1, "offset": -4096, "type": "UINT", "name": "DOPPLER MEAN VELOCITY RADIAL"},
"0 21 003": {"bits": 7, "scale": -1, "offset": -5, "type": "UINT", "name": "DIFFERENTIAL REFLECTIVITY"},
"0 21 014": {"bits": 13, "scale": -1, "offset": -4096, "type": "UINT", "name": "DOPPLER MEAN VELOCITY RADIAL"},
"0 21 022": {"bits": 5, "scale": 0, "offset": 0, "type": "UINT", "name": "METEO [SFG NOTE: UNKNOWN]"},
}
@ -64,6 +64,8 @@ SEQUENCES = { @@ -64,6 +64,8 @@ SEQUENCES = {
"3 01 024": ["0 05 002", "0 06 002", "0 07 001"], # LAT/LON/HEIGHT
}
DEBUG = False
# ============================================================================
# BUFR Reader
@ -137,14 +139,29 @@ class BitReader: @@ -137,14 +139,29 @@ class BitReader:
bits, scale, offset = desc["bits"], desc["scale"], desc["offset"]
dtype = desc["type"]
val = -9999999
raw_val = -9999999
if dtype == "IA5":
val = self.read_ia5(bits)
elif dtype == "INT":
val = (self.read_int(bits) + offset) * (10 ** scale)
raw_val = self.read_int(bits)
elif dtype == "UINT":
val = (self.read_uint(bits) + offset) * (10 ** scale)
else:
val = None
raw_val = self.read_uint(bits)
if dtype != "IA5":
val = (raw_val + offset) * (10 ** scale)
if "DIFFERENTIAL" in desc["name"]:
val = val - int(val > 6) * 12
# hot fix from FK code
if "DOPPLER" in desc["name"]:
if val < -50:
val = np.nan
if DEBUG:
print(f"desc_code: {desc_code}, val: {val}")
return val
@ -281,13 +298,14 @@ def parse_bufr_block(bufr_data, data_type='dBz'): @@ -281,13 +298,14 @@ def parse_bufr_block(bufr_data, data_type='dBz'):
grid = np.full(10000, np.nan, dtype=np.float32)
position = 0
n_pixels_with_data = reader.read_descriptor("0 31 002")
for _ in range(n_pixels_with_data):
n_skip = reader.read_descriptor("0 31 012")
marker = reader.read_descriptor(descriptor_code)
# Заполняем пропущенные пиксели
if n_skip > 0 and position + n_skip <= 10000:
if n_skip > 0: # and position + n_skip <= 10000:
grid[position:position + n_skip] = marker
position += n_skip
@ -306,7 +324,8 @@ def parse_bufr_block(bufr_data, data_type='dBz'): @@ -306,7 +324,8 @@ def parse_bufr_block(bufr_data, data_type='dBz'):
# поэтому здесь, в отличие от старого кода для DAT-файлов, нет необходимости применять их еще раз.
return grid
except Exception:
except Exception as e:
print(f"Error parsing BUFR block: {e}")
return None
@ -542,7 +561,7 @@ def load_npz_data(npz_path): @@ -542,7 +561,7 @@ def load_npz_data(npz_path):
'dbz': data['dbz'],
'dbzd': data['dbzd'],
'doppler': data['doppler'],
'meteo': data['meteo'],
'meteo': data['meteo'] if 'meteo' in data else np.zeros((144, 100, 100)),
'times': data['times'] if 'times' in data else None
}

Loading…
Cancel
Save