zephyr-backend/main.py
2025-01-08 12:53:55 +08:00

507 lines
16 KiB
Python

from PySide6.QtWidgets import QApplication, QMainWindow, QTableWidget, QTableWidgetItem, QHeaderView
from PySide6.QtGui import QPixmap
from PySide6.QtCore import Qt
from qt import Ui_MainWindow
from qt_material import apply_stylesheet
import pandas as pd
import sys
import os
import re
import balloon
lat = 52.21
g = 9.76
tag_balloon_once = [
[
"地形重力波",
"垂直传播方向",
"水平传播方向",
"本征(固有)频率",
"本征周期",
"本征频率与固有频率的比值(即长短轴之比)",
],
[
"垂直波长",
"水平波长",
"纬向本征相速度",
"经向本征相速度",
"垂直本征相速度",
"波动能",
],
[
"势能",
"纬向动量通量",
"经向动量通量",
"纬向风扰动振幅",
"经向风扰动振幅",
"温度扰动振幅",
],
]
def set_table_balloon_once(table: QTableWidget, data: list):
for i in range(3):
for j in range(6):
table.setItem(i, j * 2, QTableWidgetItem(tag_balloon_once[i][j]))
if data[0] == True:
data[0] = ""
else:
data[0] = ""
if data[1] == 1:
data[1] = ""
else:
data[1] = ""
for i in range(2, len(data)):
data[i] = f"{data[i]} "
data[2] += "°"
data[3] += "rad/s"
data[4] += "h"
data[6] += "km"
data[7] += "km"
for i in [8, 9, 10, 15, 16]:
data[i] += "m/s"
data[11] += "J/kg"
data[12] += "J/kg"
data[13] += "mPa"
data[14] += "mPa"
data[17] += "K"
for i in range(18):
table.setItem(i // 6, (i % 6) * 2 + 1, QTableWidgetItem(data[i]))
class MainWindow(QMainWindow, Ui_MainWindow):
comboType = [
"探空气球",
"流星雷达",
"Saber",
"TIDI",
"COSMIC",
]
comboMode = [
["重力波单次", "重力波统计"],
["重力波月统计", "潮汐波单次", "潮汐波月统计"],
["行星波月统计", "重力波单次", "重力波月统计"],
["行星波月统计"],
["行星波月统计"],
]
comboDate = [
[["", "时间"], ["起始年", "终止年"]],
[["", ""], ["", "日期"], ["", ""]],
[["起始月", "-"], ["", ""], ["", "-"]],
[["起始月", "-"]],
[["起始月", "-"]],
]
comboMap = [
[1, 2],
[3, 4, 5],
[6, 7, 8],
[9],
[10],
]
def get_date0_items(self):
match self.dataType:
case 0:
try:
self.currentDate0 = os.listdir(
f"./data/{self.comboType[self.dataType]}/{self.dataStation}")
except FileNotFoundError:
return []
return [i[-4:] for i in self.currentDate0]
case 1:
self.currentDate0 = ["2024"]
return self.currentDate0
case 2:
try:
self.currentDate0 = os.listdir(
f"./data/{self.comboType[self.dataType]}/{self.dataStation}")
except FileNotFoundError:
return []
return [re.search(r"_([A-z]+)\d{4}_", i).group(1) for i in self.currentDate0]
case _:
self.currentDate0 = ["Feb"]
return self.currentDate0
def get_date1_items(self):
if self.dataType == 0 and self.dataMode == 0:
try:
self.currentDate1 = os.listdir(
f"./data/{self.comboType[self.dataType]}/{self.dataStation}/{self.currentDate0[self.dataDate0]}")
except FileNotFoundError:
return []
return [re.search(r"_(\d{8}T\d{6}_\d+)", i).group(1) for i in self.currentDate1]
elif self.dataType == 0 and self.dataMode == 1:
return [i[-4:] for i in [end for j, end in enumerate(self.currentDate0) if j >= self.dataDate0]]
elif self.dataType == 1 and self.dataMode == 0:
self.currentDate1 = ["01"]
return self.currentDate1
elif self.dataType == 1 and self.dataMode == 1:
self.currentDate1 = ["20240317T000000"]
return self.currentDate1
elif self.dataType == 1 and self.dataMode == 2:
if self.dataStation == "黑龙江漠河":
self.currentDate1 = ["01"]
else:
self.currentDate1 = ["03"]
return self.currentDate1
elif self.dataType == 2 and self.dataMode == 1:
return [f"{i:02d}" for i in range(1, 31)]
else:
self.currentDate1 = [f"{i:02d}" for i in range(1, 13)]
return self.currentDate1
def __init__(self):
super(MainWindow, self).__init__()
self.setupUi(self)
self.stackedWidget.setCurrentIndex(0)
self.pixmap_logo = QPixmap("./data/logo.png")
self.dataType = -1
self.dataMode = -1
self.currentDate0 = []
self.currentDate1 = []
self.funcMap = [
[self.on_balloon_once_change, self.on_balloon_year_change],
[self.on_meteor_g_change, self.on_meteor_once_change,
self.on_meteor_month_change],
[self.on_Saber_twice_change, self.on_Saber_g_once_change,
self.on_Saber_g_month_change],
[self.on_TIDI_twice_change],
[self.on_COSMIC_twice_change],
]
self.clear_combo(0)
self.combo_type.addItems(self.comboType)
self.combo_type.currentTextChanged.connect(self.on_change_type)
self.combo_mode.currentTextChanged.connect(self.on_change_mode)
self.combo_station.currentTextChanged.connect(self.on_change_station)
self.combo_date0.currentTextChanged.connect(self.on_change_date0)
self.combo_date1.currentTextChanged.connect(self.on_change_date1)
s = self.size()
self.resize(s.width() + 1, s.height() + 1)
self.resize(s)
def resizeEvent(self, event):
self.on_resize()
super().resizeEvent(event)
def on_resize(self):
tmp = [
None,
None,
None,
self.label_meteor_g,
self.label_meteor_once,
self.label_meteor_month,
self.label_Saber_twice,
self.label_Saber_g_once,
self.label_Saber_g_month,
self.label_TIDI_twice,
self.label_COSMIC_twice,
]
match self.stackedWidget.currentIndex():
case 0:
l = self.label_idle_logo
p = self.pixmap_logo
l.setPixmap(p.scaled(l.size(), Qt.KeepAspectRatio,
Qt.SmoothTransformation))
case 1:
l = self.label_balloon_once
p = self.pixmap_balloon_once
if p.isNull():
self.clear_pixmap()
l.setText("无重力波")
else:
l.setPixmap(
p.scaled(l.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation))
case 2:
l = self.label_balloon_year
p = self.pixmap_balloon_year
if p.isNull():
self.clear_pixmap()
l.setText("无数据")
else:
l.setPixmap(
p.scaled(l.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation))
case 5:
i = self.stackedWidget.currentIndex()
l = tmp[i]
if self.dataStation == "黑龙江漠河":
p = QPixmap("./output/tmp_5_01.png")
else:
p = QPixmap("./output/tmp_5_03.png")
l.setPixmap(p.scaled(l.size(), Qt.KeepAspectRatio,
Qt.SmoothTransformation))
l.setCursor(Qt.CursorShape.PointingHandCursor)
case _:
i = self.stackedWidget.currentIndex()
l = tmp[i]
p = QPixmap(f"./output/tmp_{i}.png")
l.setPixmap(p.scaled(l.size(), Qt.KeepAspectRatio,
Qt.SmoothTransformation))
l.setCursor(Qt.CursorShape.PointingHandCursor)
def clear_pixmap(self):
self.pixmap_balloon_once = QPixmap()
self.pixmap_balloon_year = QPixmap()
self.pixmap_meteor_g = QPixmap()
self.pixmap_meteor_once = QPixmap()
self.pixmap_meteor_month = QPixmap()
self.pixmap_Saber_twice = QPixmap()
self.pixmap_Saber_g_once = QPixmap()
self.pixmap_Saber_g_month = QPixmap()
self.pixmap_TIDI_twice = QPixmap()
self.pixmap_COSMIC_twice = QPixmap()
self.table_balloon_once.setVisible(False)
for l in [
self.label_balloon_once,
self.label_balloon_year,
self.label_meteor_g,
self.label_meteor_once,
self.label_meteor_month,
self.label_Saber_twice,
self.label_Saber_g_once,
self.label_Saber_g_month,
self.label_TIDI_twice,
self.label_COSMIC_twice,
]:
l.setCursor(Qt.CursorShape.ArrowCursor)
def clear_combo(self, level: int):
self.clear_pixmap()
self.on_resize()
self.stackedWidget.setCurrentIndex(0)
for i, combo in enumerate(
[
self.combo_type,
self.combo_mode,
self.combo_station,
self.combo_date0,
self.combo_date1,
]
):
if i >= level:
combo.clear()
combo.setEnabled(i <= level)
def on_change_type(self):
if self.combo_type.currentIndex() < 0:
return
self.clear_combo(1)
self.dataType = self.combo_type.currentIndex()
self.combo_mode.addItems(self.comboMode[self.dataType])
self.combo_date0.setPlaceholderText("-")
self.combo_date1.setPlaceholderText("-")
def on_change_mode(self):
if self.combo_mode.currentIndex() < 0:
return
self.clear_combo(2)
self.dataMode = self.combo_mode.currentIndex()
if self.dataType < 2:
self.combo_station.setPlaceholderText("台站")
else:
self.combo_station.setPlaceholderText("")
list_station = []
try:
# list_station = [i for i in os.listdir(f"./data/{self.comboType[self.dataType]}") if i.encode("utf-8").isupper()]
list_station = [i for i in os.listdir(
f"./data/{self.comboType[self.dataType]}")]
except FileNotFoundError:
return
self.combo_station.addItems(list_station)
date0, date1 = self.comboDate[self.dataType][self.dataMode]
self.combo_date0.setPlaceholderText(date0)
self.combo_date1.setPlaceholderText(date1)
def on_change_station(self):
if self.combo_station.currentIndex() < 0:
return
self.clear_combo(3)
self.dataStation = self.combo_station.currentText()
self.combo_date0.addItems(self.get_date0_items())
def on_change_date0(self):
if self.combo_date0.currentIndex() < 0:
return
self.clear_combo(4)
self.dataDate0 = self.combo_date0.currentIndex()
if self.dataType < 2 or (self.dataType == 2 and self.dataMode == 1):
self.combo_date1.addItems(self.get_date1_items())
return
self.combo_date1.setEnabled(False)
self.stackedWidget.setCurrentIndex(
self.comboMap[self.dataType][self.dataMode])
if f := self.funcMap[self.dataType][self.dataMode]:
f()
def on_change_date1(self):
if self.combo_date1.currentIndex() < 0:
return
self.dataDate1 = self.combo_date1.currentIndex()
self.stackedWidget.setCurrentIndex(
self.comboMap[self.dataType][self.dataMode])
if f := self.funcMap[self.dataType][self.dataMode]:
f()
def on_balloon_once_change(self):
path = os.path.join("./data/探空气球", self.dataStation,
self.currentDate0[self.dataDate0], self.currentDate1[self.dataDate1])
try:
data = balloon.read_data(path)
except Exception as e:
print(e)
return
path = "./output" + path[6:-2] + "png"
os.makedirs(os.path.dirname(path), exist_ok=True)
result = balloon.plot_once(data, path, lat, g)
if len(result) == 0:
self.pixmap_balloon_once = QPixmap()
self.on_resize()
return
self.pixmap_balloon_once = QPixmap(path)
self.label_balloon_once.setCursor(Qt.CursorShape.PointingHandCursor)
t = self.table_balloon_once
t.clear()
t.setRowCount(3)
t.setColumnCount(12)
t.setVisible(True)
t.verticalHeader().setHidden(True)
t.horizontalHeader().setHidden(True)
t.verticalScrollBar().setHidden(True)
t.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeMode.Stretch)
set_table_balloon_once(t, result)
t.setMaximumHeight(t.rowHeight(0) * 3)
s = self.size()
self.resize(s.width() + 1, s.height() + 1)
self.resize(s)
def on_balloon_year_change(self):
columns = [
"file_name",
"c",
"a",
"b",
"omega_upper",
"w_f",
"ver_wave_len",
"hori_wave_len",
"c_x",
"c_y",
"c_z",
"Ek",
"E_p",
"MFu",
"MFv",
"u1",
"v1",
"T1",
"zhou_qi",
]
combined_df = pd.DataFrame()
for i in range(self.dataDate1 + 1):
path = f"./output/探空气球/{self.dataStation}/{self.currentDate0[self.dataDate0 + i]}.csv"
os.makedirs(os.path.dirname(path), exist_ok=True)
if os.path.exists(path):
year_df = pd.read_csv(path)
combined_df = pd.concat([combined_df, year_df])
continue
folder = "./data" + path[8:-4]
year_df = pd.DataFrame()
for file in os.listdir(folder):
print(file)
data = balloon.read_data(os.path.join(folder, file))
try:
wave = balloon.extract_wave(data, lat, g)
except Exception:
wave = []
if len(wave) == 0:
continue
c = balloon.is_terrain_wave(data, lat, g)
wave.insert(0, c)
wave.insert(0, file)
line = pd.DataFrame([wave], columns=columns)
year_df = pd.concat([year_df, line])
combined_df = pd.concat([combined_df, year_df])
year_df.to_csv(path, index=False)
path = f"./output/探空气球/{self.dataStation}/{self.currentDate0[self.dataDate0]}_{self.dataDate1}.png"
if not balloon.plot_year(combined_df, path, lat, g):
self.pixmap_balloon_year = QPixmap()
self.on_resize()
return
self.pixmap_balloon_year = QPixmap(path)
self.label_balloon_year.setCursor(Qt.CursorShape.PointingHandCursor)
s = self.size()
self.resize(s.width() + 1, s.height() + 1)
self.resize(s)
def on_meteor_g_change(self):
self.on_resize()
def on_meteor_once_change(self):
self.on_resize()
def on_meteor_month_change(self):
self.on_resize()
def on_Saber_twice_change(self):
self.spin_Saber_twice_lat.setValue(0)
self.spin_Saber_twice_alt.setValue(90)
self.on_resize()
def on_Saber_g_once_change(self):
self.spin_Saber_g_once_lat.setValue(0)
self.spin_Saber_g_once_lon.setValue(0)
self.spin_Saber_g_once_alt.setValue(90)
self.on_resize()
def on_Saber_g_month_change(self):
self.spin_Saber_g_month_lat.setValue(0)
self.spin_Saber_g_month_alt.setValue(90)
self.on_resize()
def on_TIDI_twice_change(self):
self.spin_TIDI_twice_lat.setValue(0)
self.spin_TIDI_twice_alt.setValue(90)
self.on_resize()
def on_COSMIC_twice_change(self):
self.spin_COSMIC_twice_lat.setValue(0)
self.spin_COSMIC_twice_alt.setValue(40)
self.on_resize()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
apply_stylesheet(app, theme="light_blue.xml", invert_secondary=True)
window.show()
sys.exit(app.exec())