Spaces:
Sleeping
Sleeping
Commit
·
2bd4899
1
Parent(s):
d03ae4c
只留下拉選單跟滑桿
Browse files
app.py
CHANGED
|
@@ -838,13 +838,13 @@ def step1_load_mseed_and_select_stations(event_name):
|
|
| 838 |
)
|
| 839 |
|
| 840 |
logger.info("[步驟 1] 完成 - mseed 已載入,測站已選擇")
|
| 841 |
-
return st, selected_stations, station_map, None
|
| 842 |
|
| 843 |
except Exception as e:
|
| 844 |
logger.error(f"[步驟 1] 發生錯誤: {e}")
|
| 845 |
import traceback
|
| 846 |
traceback.print_exc()
|
| 847 |
-
return None, None, None, None
|
| 848 |
|
| 849 |
|
| 850 |
# ============ 步驟 2:提取波形(使用快取的 stream + stations)============
|
|
@@ -879,13 +879,13 @@ def step2_extract_and_plot_waveforms(cached_stream, cached_stations, event_name,
|
|
| 879 |
waveform_plot = plot_waveform(cached_stream, cached_stations, first_pick, duration)
|
| 880 |
|
| 881 |
logger.info(f"[步驟 2] 完成 - 已提取 {len(waveforms)} 個測站的波形")
|
| 882 |
-
return waveforms, station_info_list, waveform_plot
|
| 883 |
|
| 884 |
except Exception as e:
|
| 885 |
logger.error(f"[步驟 2] 發生錯誤: {e}")
|
| 886 |
import traceback
|
| 887 |
traceback.print_exc()
|
| 888 |
-
return None, None, None
|
| 889 |
|
| 890 |
|
| 891 |
# ============ 步驟 3:執行模型推論(使用快取的波形)============
|
|
@@ -1015,12 +1015,11 @@ with gr.Blocks(title="TTSAM 震度預測系統", fill_height=True) as demo:
|
|
| 1015 |
with gr.Row():
|
| 1016 |
# 左上:使用步驟與狀態顯示
|
| 1017 |
with gr.Column(scale=1):
|
| 1018 |
-
gr.Markdown("##
|
| 1019 |
gr.Markdown(
|
| 1020 |
"""
|
| 1021 |
-
|
| 1022 |
-
|
| 1023 |
-
3. 點擊「執行預測」查看震度分布
|
| 1024 |
|
| 1025 |
系統會自動選擇距離震央最近的 25 個測站,並快取資料避免重複讀檔。
|
| 1026 |
"""
|
|
@@ -1031,16 +1030,15 @@ with gr.Blocks(title="TTSAM 震度預測系統", fill_height=True) as demo:
|
|
| 1031 |
value=list(earthquake_metadata.keys())[0],
|
| 1032 |
label="選擇地震事件",
|
| 1033 |
)
|
|
|
|
|
|
|
|
|
|
| 1034 |
# ========== 中層:輸入測站地圖與波形圖 ==========
|
| 1035 |
with gr.Row():
|
| 1036 |
# 中左:輸入測站地圖
|
| 1037 |
with gr.Column(scale=1):
|
| 1038 |
gr.Markdown("## 輸入測站分布")
|
| 1039 |
input_station_map = gr.Plot(label="輸入測站地圖")
|
| 1040 |
-
load_waveform_btn = gr.Button("📊 載入波形", variant="secondary", scale=1)
|
| 1041 |
-
predict_btn = gr.Button(
|
| 1042 |
-
"🔮 執行預測", variant="primary", scale=1, interactive=False
|
| 1043 |
-
)
|
| 1044 |
|
| 1045 |
# 中右:輸入波形
|
| 1046 |
with gr.Column(scale=1):
|
|
@@ -1048,10 +1046,7 @@ with gr.Blocks(title="TTSAM 震度預測系統", fill_height=True) as demo:
|
|
| 1048 |
waveform_plot = gr.Plot(
|
| 1049 |
label="地震波形(選定的 25 個測站)",
|
| 1050 |
)
|
| 1051 |
-
|
| 1052 |
-
duration_slider = gr.Slider(
|
| 1053 |
-
2, 15, value=15, step=1, label="P 波後時間 (秒)"
|
| 1054 |
-
)
|
| 1055 |
|
| 1056 |
# ========== 下層:實際觀測 vs 預測結果 ==========
|
| 1057 |
with gr.Row():
|
|
@@ -1078,51 +1073,45 @@ with gr.Blocks(title="TTSAM 震度預測系統", fill_height=True) as demo:
|
|
| 1078 |
|
| 1079 |
# ========== 事件綁定(使用鏈式觸發 + gr.State 快取)==========
|
| 1080 |
|
| 1081 |
-
# 【觸發點 1
|
| 1082 |
event_dropdown.change(
|
| 1083 |
fn=step1_load_mseed_and_select_stations,
|
| 1084 |
inputs=[event_dropdown],
|
| 1085 |
-
outputs=[cached_stream, cached_stations, input_station_map, waveform_plot
|
| 1086 |
).then( # 鏈式觸發步驟 2
|
| 1087 |
fn=step2_extract_and_plot_waveforms,
|
| 1088 |
inputs=[cached_stream, cached_stations, event_dropdown, duration_slider],
|
| 1089 |
-
outputs=[cached_waveforms, cached_station_info, waveform_plot
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1090 |
)
|
| 1091 |
|
| 1092 |
-
# 【觸發點 2
|
| 1093 |
duration_slider.change(
|
| 1094 |
fn=step2_extract_and_plot_waveforms,
|
| 1095 |
inputs=[cached_stream, cached_stations, event_dropdown, duration_slider],
|
| 1096 |
-
outputs=[cached_waveforms, cached_station_info, waveform_plot
|
| 1097 |
-
)
|
| 1098 |
-
|
| 1099 |
-
# 【觸發點 3】載入波形按鈕:手動觸發步驟 1 → 步驟 2
|
| 1100 |
-
load_waveform_btn.click(
|
| 1101 |
-
fn=step1_load_mseed_and_select_stations,
|
| 1102 |
-
inputs=[event_dropdown],
|
| 1103 |
-
outputs=[cached_stream, cached_stations, input_station_map, waveform_plot, predict_btn]
|
| 1104 |
-
).then(
|
| 1105 |
-
fn=step2_extract_and_plot_waveforms,
|
| 1106 |
-
inputs=[cached_stream, cached_stations, event_dropdown, duration_slider],
|
| 1107 |
-
outputs=[cached_waveforms, cached_station_info, waveform_plot, predict_btn]
|
| 1108 |
-
)
|
| 1109 |
-
|
| 1110 |
-
# 【觸發點 4】執行預測:使用快取的波形執行步驟 3
|
| 1111 |
-
predict_btn.click(
|
| 1112 |
fn=step3_predict_intensity,
|
| 1113 |
inputs=[cached_waveforms, cached_station_info, event_dropdown],
|
| 1114 |
outputs=[observed_intensity_image, predicted_intensity_map]
|
| 1115 |
)
|
| 1116 |
|
| 1117 |
-
#
|
| 1118 |
demo.load(
|
| 1119 |
fn=step1_load_mseed_and_select_stations,
|
| 1120 |
inputs=[event_dropdown],
|
| 1121 |
-
outputs=[cached_stream, cached_stations, input_station_map, waveform_plot
|
| 1122 |
).then(
|
| 1123 |
fn=step2_extract_and_plot_waveforms,
|
| 1124 |
inputs=[cached_stream, cached_stations, event_dropdown, duration_slider],
|
| 1125 |
-
outputs=[cached_waveforms, cached_station_info, waveform_plot
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1126 |
)
|
| 1127 |
|
| 1128 |
demo.launch()
|
|
|
|
| 838 |
)
|
| 839 |
|
| 840 |
logger.info("[步驟 1] 完成 - mseed 已載入,測站已選擇")
|
| 841 |
+
return st, selected_stations, station_map, None
|
| 842 |
|
| 843 |
except Exception as e:
|
| 844 |
logger.error(f"[步驟 1] 發生錯誤: {e}")
|
| 845 |
import traceback
|
| 846 |
traceback.print_exc()
|
| 847 |
+
return None, None, None, None
|
| 848 |
|
| 849 |
|
| 850 |
# ============ 步驟 2:提取波形(使用快取的 stream + stations)============
|
|
|
|
| 879 |
waveform_plot = plot_waveform(cached_stream, cached_stations, first_pick, duration)
|
| 880 |
|
| 881 |
logger.info(f"[步驟 2] 完成 - 已提取 {len(waveforms)} 個測站的波形")
|
| 882 |
+
return waveforms, station_info_list, waveform_plot
|
| 883 |
|
| 884 |
except Exception as e:
|
| 885 |
logger.error(f"[步驟 2] 發生錯誤: {e}")
|
| 886 |
import traceback
|
| 887 |
traceback.print_exc()
|
| 888 |
+
return None, None, None
|
| 889 |
|
| 890 |
|
| 891 |
# ============ 步驟 3:執行模型推論(使用快取的波形)============
|
|
|
|
| 1015 |
with gr.Row():
|
| 1016 |
# 左上:使用步驟與狀態顯示
|
| 1017 |
with gr.Column(scale=1):
|
| 1018 |
+
gr.Markdown("## 使用說明")
|
| 1019 |
gr.Markdown(
|
| 1020 |
"""
|
| 1021 |
+
- **選擇地震事件**:自動載入測站並執行預測
|
| 1022 |
+
- **調整時間滑桿**:即時更新波形與震度預測
|
|
|
|
| 1023 |
|
| 1024 |
系統會自動選擇距離震央最近的 25 個測站,並快取資料避免重複讀檔。
|
| 1025 |
"""
|
|
|
|
| 1030 |
value=list(earthquake_metadata.keys())[0],
|
| 1031 |
label="選擇地震事件",
|
| 1032 |
)
|
| 1033 |
+
duration_slider = gr.Slider(
|
| 1034 |
+
2, 15, value=15, step=1, label="P 波後時間 (秒)"
|
| 1035 |
+
)
|
| 1036 |
# ========== 中層:輸入測站地圖與波形圖 ==========
|
| 1037 |
with gr.Row():
|
| 1038 |
# 中左:輸入測站地圖
|
| 1039 |
with gr.Column(scale=1):
|
| 1040 |
gr.Markdown("## 輸入測站分布")
|
| 1041 |
input_station_map = gr.Plot(label="輸入測站地圖")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1042 |
|
| 1043 |
# 中右:輸入波形
|
| 1044 |
with gr.Column(scale=1):
|
|
|
|
| 1046 |
waveform_plot = gr.Plot(
|
| 1047 |
label="地震波形(選定的 25 個測站)",
|
| 1048 |
)
|
| 1049 |
+
|
|
|
|
|
|
|
|
|
|
| 1050 |
|
| 1051 |
# ========== 下層:實際觀測 vs 預測結果 ==========
|
| 1052 |
with gr.Row():
|
|
|
|
| 1073 |
|
| 1074 |
# ========== 事件綁定(使用鏈式觸發 + gr.State 快取)==========
|
| 1075 |
|
| 1076 |
+
# 【觸發點 1】事件切換:自動執行完整流程 步驟 1 → 步驟 2 → 步驟 3
|
| 1077 |
event_dropdown.change(
|
| 1078 |
fn=step1_load_mseed_and_select_stations,
|
| 1079 |
inputs=[event_dropdown],
|
| 1080 |
+
outputs=[cached_stream, cached_stations, input_station_map, waveform_plot]
|
| 1081 |
).then( # 鏈式觸發步驟 2
|
| 1082 |
fn=step2_extract_and_plot_waveforms,
|
| 1083 |
inputs=[cached_stream, cached_stations, event_dropdown, duration_slider],
|
| 1084 |
+
outputs=[cached_waveforms, cached_station_info, waveform_plot]
|
| 1085 |
+
).then( # 鏈式觸發步驟 3
|
| 1086 |
+
fn=step3_predict_intensity,
|
| 1087 |
+
inputs=[cached_waveforms, cached_station_info, event_dropdown],
|
| 1088 |
+
outputs=[observed_intensity_image, predicted_intensity_map]
|
| 1089 |
)
|
| 1090 |
|
| 1091 |
+
# 【觸發點 2】時間範圍調整:自動執行步驟 2 → 步驟 3(不重新讀檔)
|
| 1092 |
duration_slider.change(
|
| 1093 |
fn=step2_extract_and_plot_waveforms,
|
| 1094 |
inputs=[cached_stream, cached_stations, event_dropdown, duration_slider],
|
| 1095 |
+
outputs=[cached_waveforms, cached_station_info, waveform_plot]
|
| 1096 |
+
).then( # 鏈式觸發步驟 3
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1097 |
fn=step3_predict_intensity,
|
| 1098 |
inputs=[cached_waveforms, cached_station_info, event_dropdown],
|
| 1099 |
outputs=[observed_intensity_image, predicted_intensity_map]
|
| 1100 |
)
|
| 1101 |
|
| 1102 |
+
# 【冷啟動】應用載入時自動執行完整流程 步驟 1 → 步驟 2 → 步驟 3
|
| 1103 |
demo.load(
|
| 1104 |
fn=step1_load_mseed_and_select_stations,
|
| 1105 |
inputs=[event_dropdown],
|
| 1106 |
+
outputs=[cached_stream, cached_stations, input_station_map, waveform_plot]
|
| 1107 |
).then(
|
| 1108 |
fn=step2_extract_and_plot_waveforms,
|
| 1109 |
inputs=[cached_stream, cached_stations, event_dropdown, duration_slider],
|
| 1110 |
+
outputs=[cached_waveforms, cached_station_info, waveform_plot]
|
| 1111 |
+
).then(
|
| 1112 |
+
fn=step3_predict_intensity,
|
| 1113 |
+
inputs=[cached_waveforms, cached_station_info, event_dropdown],
|
| 1114 |
+
outputs=[observed_intensity_image, predicted_intensity_map]
|
| 1115 |
)
|
| 1116 |
|
| 1117 |
demo.launch()
|