Spaces:
Sleeping
Sleeping
Commit
·
83df282
1
Parent(s):
6663675
docs: optimize initial workflow loading and event synchronization for improved user experience
Browse files- app.py +71 -5
- changelog.md +31 -13
- spec/plan.md +3 -48
- spec/task.md +4 -0
app.py
CHANGED
|
@@ -1167,6 +1167,72 @@ def predict_intensity(event_name, start_time, duration, epicenter_lon, epicenter
|
|
| 1167 |
return None, None, f"錯誤: {str(e)}"
|
| 1168 |
|
| 1169 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1170 |
# ============ Gradio 介面 ============
|
| 1171 |
|
| 1172 |
with gr.Blocks(title="TTSAM 震度預測系統") as demo:
|
|
@@ -1248,9 +1314,9 @@ with gr.Blocks(title="TTSAM 震度預測系統") as demo:
|
|
| 1248 |
|
| 1249 |
# 綁定事件
|
| 1250 |
event_dropdown.change(
|
| 1251 |
-
fn=
|
| 1252 |
inputs=[event_dropdown, start_slider, duration_slider, epicenter_lon_input, epicenter_lat_input],
|
| 1253 |
-
outputs=[input_station_map, waveform_plot, info_output, observed_intensity_image]
|
| 1254 |
)
|
| 1255 |
|
| 1256 |
load_waveform_btn.click(
|
|
@@ -1265,11 +1331,11 @@ with gr.Blocks(title="TTSAM 震度預測系統") as demo:
|
|
| 1265 |
outputs=[observed_intensity_image, predicted_intensity_map, stats_output]
|
| 1266 |
)
|
| 1267 |
|
| 1268 |
-
#
|
| 1269 |
demo.load(
|
| 1270 |
-
fn=
|
| 1271 |
inputs=[event_dropdown, start_slider, duration_slider, epicenter_lon_input, epicenter_lat_input],
|
| 1272 |
-
outputs=[input_station_map, waveform_plot, info_output, observed_intensity_image]
|
| 1273 |
)
|
| 1274 |
|
| 1275 |
demo.launch()
|
|
|
|
| 1167 |
return None, None, f"錯誤: {str(e)}"
|
| 1168 |
|
| 1169 |
|
| 1170 |
+
def on_event_change(event_name, start_time, duration, epicenter_lon, epicenter_lat):
|
| 1171 |
+
"""
|
| 1172 |
+
事件切換或波形參數變更時,更新波形視圖(不執行推論)
|
| 1173 |
+
|
| 1174 |
+
返回:station_map_html, waveform_plot, info_text, observed_img
|
| 1175 |
+
(與事件變更事件綁定的回調函數)
|
| 1176 |
+
|
| 1177 |
+
spec #2:測站選擇上限 (25 站)、波形取樣率 (100 Hz)、時間窗長度 (30 秒)
|
| 1178 |
+
"""
|
| 1179 |
+
try:
|
| 1180 |
+
station_map_html, waveform_plot, info_text, _ = load_and_display_waveform(
|
| 1181 |
+
event_name, start_time, duration, epicenter_lon, epicenter_lat
|
| 1182 |
+
)
|
| 1183 |
+
observed_img = load_observed_intensity_image(event_name)
|
| 1184 |
+
return station_map_html, waveform_plot, info_text, observed_img
|
| 1185 |
+
except Exception as e:
|
| 1186 |
+
logger.error(f"事件變更回調發生錯誤: {e}")
|
| 1187 |
+
return None, None, f"錯誤: {str(e)}", None
|
| 1188 |
+
|
| 1189 |
+
|
| 1190 |
+
def on_full_workflow(event_name, start_time, duration, epicenter_lon, epicenter_lat):
|
| 1191 |
+
"""
|
| 1192 |
+
執行完整的工作流:波形載入 → 測站選擇 → 推論 → 結果展示
|
| 1193 |
+
|
| 1194 |
+
此函數用於首次應用加載與事件切換時自動執行完整流程
|
| 1195 |
+
|
| 1196 |
+
返回所有必要的 UI 組件輸出:
|
| 1197 |
+
(station_map_html, waveform_plot, info_text, predicted_map_html, stats_text, observed_img)
|
| 1198 |
+
|
| 1199 |
+
spec #2:測站選擇上限 (25 站)、波形取樣率 (100 Hz)、時間窗長度 (30 秒)
|
| 1200 |
+
spec #3:推論流程、PGA → 震度轉換
|
| 1201 |
+
"""
|
| 1202 |
+
try:
|
| 1203 |
+
logger.info(f"[on_full_workflow] 開始執行完整工作流 - 事件: {event_name}")
|
| 1204 |
+
|
| 1205 |
+
# 步驟 1: 載入波形
|
| 1206 |
+
logger.info(f"[on_full_workflow] 步驟 1/3: 波形載入...")
|
| 1207 |
+
station_map_html, waveform_plot, info_text, _ = load_and_display_waveform(
|
| 1208 |
+
event_name, start_time, duration, epicenter_lon, epicenter_lat
|
| 1209 |
+
)
|
| 1210 |
+
|
| 1211 |
+
if station_map_html is None:
|
| 1212 |
+
logger.error("[on_full_workflow] 波形載入失敗")
|
| 1213 |
+
return None, None, info_text, None, "波形載入失敗", None
|
| 1214 |
+
|
| 1215 |
+
# 步驟 2: 執行推論
|
| 1216 |
+
logger.info(f"[on_full_workflow] 步驟 2/3: 模型推論...")
|
| 1217 |
+
observed_img, predicted_map_html, stats_text = predict_intensity(
|
| 1218 |
+
event_name, start_time, duration, epicenter_lon, epicenter_lat
|
| 1219 |
+
)
|
| 1220 |
+
|
| 1221 |
+
if predicted_map_html is None:
|
| 1222 |
+
logger.error("[on_full_workflow] 推論失敗")
|
| 1223 |
+
return station_map_html, waveform_plot, info_text, None, stats_text, observed_img
|
| 1224 |
+
|
| 1225 |
+
logger.info(f"[on_full_workflow] 步驟 3/3: 完成")
|
| 1226 |
+
|
| 1227 |
+
return station_map_html, waveform_plot, info_text, predicted_map_html, stats_text, observed_img
|
| 1228 |
+
|
| 1229 |
+
except Exception as e:
|
| 1230 |
+
logger.error(f"[on_full_workflow] 完整工作流發生錯誤: {e}")
|
| 1231 |
+
import traceback
|
| 1232 |
+
traceback.print_exc()
|
| 1233 |
+
return None, None, f"錯誤: {str(e)}", None, f"錯誤: {str(e)}", None
|
| 1234 |
+
|
| 1235 |
+
|
| 1236 |
# ============ Gradio 介面 ============
|
| 1237 |
|
| 1238 |
with gr.Blocks(title="TTSAM 震度預測系統") as demo:
|
|
|
|
| 1314 |
|
| 1315 |
# 綁定事件
|
| 1316 |
event_dropdown.change(
|
| 1317 |
+
fn=on_full_workflow,
|
| 1318 |
inputs=[event_dropdown, start_slider, duration_slider, epicenter_lon_input, epicenter_lat_input],
|
| 1319 |
+
outputs=[input_station_map, waveform_plot, info_output, predicted_intensity_map, stats_output, observed_intensity_image]
|
| 1320 |
)
|
| 1321 |
|
| 1322 |
load_waveform_btn.click(
|
|
|
|
| 1331 |
outputs=[observed_intensity_image, predicted_intensity_map, stats_output]
|
| 1332 |
)
|
| 1333 |
|
| 1334 |
+
# 應用啟動時自動執行完整工作流
|
| 1335 |
demo.load(
|
| 1336 |
+
fn=on_full_workflow,
|
| 1337 |
inputs=[event_dropdown, start_slider, duration_slider, epicenter_lon_input, epicenter_lat_input],
|
| 1338 |
+
outputs=[input_station_map, waveform_plot, info_output, predicted_intensity_map, stats_output, observed_intensity_image]
|
| 1339 |
)
|
| 1340 |
|
| 1341 |
demo.launch()
|
changelog.md
CHANGED
|
@@ -4,8 +4,38 @@
|
|
| 4 |
|
| 5 |
## [Unreleased]
|
| 6 |
|
|
|
|
|
|
|
| 7 |
### Added
|
| 8 |
-
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
- 應用啟動時自動載入預設地震事件的波形地圖(測站分布 + 波形圖)
|
| 10 |
- 地震事件切換時同步自動更新波形地圖與實際觀測圖
|
| 11 |
- 新增 `on_event_change()` callback 協調多個 UI 組件的聯動更新
|
|
@@ -35,18 +65,6 @@
|
|
| 35 |
- `event_dropdown.change` 現使用 `on_event_change()` 而非 `on_event_select()`
|
| 36 |
- 一次事件切換可同時更新波形地圖、波形圖、實際觀測圖
|
| 37 |
|
| 38 |
-
### Fixed
|
| 39 |
-
- (待填)
|
| 40 |
-
|
| 41 |
-
### Deprecated
|
| 42 |
-
- (待填)
|
| 43 |
-
|
| 44 |
-
### Removed
|
| 45 |
-
- (待填)
|
| 46 |
-
|
| 47 |
-
### Security
|
| 48 |
-
- (待填)
|
| 49 |
-
|
| 50 |
---
|
| 51 |
|
| 52 |
## [1.0.0] — 初版 (Initial Release)
|
|
|
|
| 4 |
|
| 5 |
## [Unreleased]
|
| 6 |
|
| 7 |
+
## [Sprint 002] — 首次載入完整工作流優化 (2025-10-26)
|
| 8 |
+
|
| 9 |
### Added
|
| 10 |
+
- **首次載入自動完整工作流**
|
| 11 |
+
- 應用啟動時自動執行完整工作流:波形載入 → 測站選擇 → 模型推論 → 地圖展示
|
| 12 |
+
- 新增 `on_full_workflow()` 函數,整合波形與推論步驟,一次性返回所有 UI 組件結果
|
| 13 |
+
- 首次打開應用時立即顯示完整的演示內容,無需用戶點擊任何按鈕
|
| 14 |
+
|
| 15 |
+
- **事件切換同步更新**
|
| 16 |
+
- 修改 `event_dropdown.change` 事件綁定,改用 `on_full_workflow()` 完整工作流
|
| 17 |
+
- 選擇不同地震事件時,所有視圖同步自動更新(波形、地圖、統計、實際觀測圖)
|
| 18 |
+
|
| 19 |
+
- **波形視圖專用回調**
|
| 20 |
+
- 新增 `on_event_change()` 函數,支持用戶手動調整時間窗後重新載入波形視圖
|
| 21 |
+
- 保留「載入波形」按鈕與「執行預測」按鈕的獨立操作選項
|
| 22 |
+
|
| 23 |
+
### Changed
|
| 24 |
+
- **Gradio 事件系統重構**
|
| 25 |
+
- `demo.load` 從 `on_event_change` 改為 `on_full_workflow`,首次加載自動執行推論
|
| 26 |
+
- `event_dropdown.change` 從 `on_event_change` 改為 `on_full_workflow`,事件切換自動推論
|
| 27 |
+
|
| 28 |
+
### Improved
|
| 29 |
+
- **使用者體驗**
|
| 30 |
+
- 應用首次啟動時不再出現空白頁面,立即展示完整的互動式演示
|
| 31 |
+
- 事件切換更加流暢,所有視圖實時同步,提升展示效果
|
| 32 |
+
|
| 33 |
+
---
|
| 34 |
+
|
| 35 |
+
## [Sprint 001] — 波形地圖自動載入 (2025-10-26)
|
| 36 |
+
|
| 37 |
+
### Added
|
| 38 |
+
- **UI 流程自動化**
|
| 39 |
- 應用啟動時自動載入預設地震事件的波形地圖(測站分布 + 波形圖)
|
| 40 |
- 地震事件切換時同步自動更新波形地圖與實際觀測圖
|
| 41 |
- 新增 `on_event_change()` callback 協調多個 UI 組件的聯動更新
|
|
|
|
| 65 |
- `event_dropdown.change` 現使用 `on_event_change()` 而非 `on_event_select()`
|
| 66 |
- 一次事件切換可同時更新波形地圖、波形圖、實際觀測圖
|
| 67 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 68 |
---
|
| 69 |
|
| 70 |
## [1.0.0] — 初版 (Initial Release)
|
spec/plan.md
CHANGED
|
@@ -1,54 +1,9 @@
|
|
| 1 |
-
# 迭代計畫 (plan.md) —
|
| 2 |
|
| 3 |
-
>
|
|
|
|
| 4 |
|
| 5 |
-
## 迭代資訊
|
| 6 |
|
| 7 |
-
| 項目 | 值 |
|
| 8 |
-
|-----|-----|
|
| 9 |
-
| Sprint 編號 | 001 |
|
| 10 |
-
| 開始日期 | 2025-10-26 |
|
| 11 |
-
| 預計結束日期 | 2025-10-26 |
|
| 12 |
-
| 負責人 | 使用者 |
|
| 13 |
-
|
| 14 |
-
## 迭代目標 (Goal)
|
| 15 |
-
|
| 16 |
-
**提升波形地圖的可用性與互動流程**
|
| 17 |
-
|
| 18 |
-
- 應用啟動時,自動載入預設地震事件的波形地圖(選定測站分布 + 波形圖)
|
| 19 |
-
- 使用者切換地震事件時,同步自動更新波形地圖,無需手動點擊「載入波形」按鈕
|
| 20 |
-
- 優化使用者體驗,減少操作步驟
|
| 21 |
-
|
| 22 |
-
## 範圍 (Scope)
|
| 23 |
-
|
| 24 |
-
| 模組 | 涉及檔案 | 變更類型 |
|
| 25 |
-
|-----|--------|---------|
|
| 26 |
-
| UI 工作流 | `app.py`(Gradio Blocks 事件綁定) | feature / refactor |
|
| 27 |
-
| 無規格變更 | - | N/A |
|
| 28 |
-
|
| 29 |
-
## 驗收標準 (Acceptance Criteria)
|
| 30 |
-
|
| 31 |
-
- [x] 應用啟動時,預設地震事件的波形地圖自動顯示
|
| 32 |
-
- [x] 選擇不同地震事件時,波形地圖同步自動更新
|
| 33 |
-
- [x] 「載入波形」按鈕保留可用,允許使用者手動重新載入
|
| 34 |
-
- [x] 實際觀測震度圖亦在事件切換時同步更新
|
| 35 |
-
- [x] 無新增 WARNING/ERROR 日誌
|
| 36 |
-
|
| 37 |
-
## 任務拆解 (Tasks)
|
| 38 |
-
|
| 39 |
-
### 任務 1: 在 Gradio 初始化時自動載入預設地震事件的波形
|
| 40 |
-
- **描述**:於 Gradio Blocks 定義後,新增 `on_load` 事件,使應用啟動時自動調用 `load_and_display_waveform()`
|
| 41 |
-
- **涉及檔案**:`app.py`(Gradio 事件綁定部分,L1310-1340)
|
| 42 |
-
- **變更**:
|
| 43 |
-
- 在 demo.load 事件中綁定預設參數(事件、時間範圍、震央位置)
|
| 44 |
-
- 自動填充波形地圖、波形圖、狀態訊息
|
| 45 |
-
- **驗收**:應用載入後,輸入測站地圖與波形圖立即顯示
|
| 46 |
-
|
| 47 |
-
### 任務 2: 地震事件切換時自動更新波形地圖
|
| 48 |
-
- **描述**:修改 `event_dropdown.change` 事件綁定,使其同時更新 **波形地圖** 與 **實際觀測圖**
|
| 49 |
-
- **涉及檔案**:`app.py`(L1331-1335)
|
| 50 |
-
- **變更**:
|
| 51 |
-
- 將 `event_dropdown.change` 的 callback 從單純的 `on_event_select` 改為同時調用波形載入邏輯
|
| 52 |
- 新增 callback 函數 `on_event_change()` 負責協調所有更新
|
| 53 |
- **驗收**:切換事件時,波形地圖、波形圖、實際觀測圖同步更新
|
| 54 |
|
|
|
|
| 1 |
+
# 迭代計畫 (plan.md) — 首次載入完整工作流優化 [ARCHIVED]
|
| 2 |
|
| 3 |
+
> ⏹️ **本迭代已完成** — 此檔案為 Sprint 002 的臨時計畫文件,已歸檔
|
| 4 |
+
> 下次迭代時將重新生成 `spec/plan.md`。若需重新執行此迭代,請參考 `changelog.md` 的 Sprint 002 摘要。
|
| 5 |
|
|
|
|
| 6 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
- 新增 callback 函數 `on_event_change()` 負責協調所有更新
|
| 8 |
- **驗收**:切換事件時,波形地圖、波形圖、實際觀測圖同步更新
|
| 9 |
|
spec/task.md
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 任務拆解 (task.md) — 首次載入完整工作流優化 [ARCHIVED]
|
| 2 |
+
|
| 3 |
+
> ⏹️ **本迭代已完成** — 此檔案為 Sprint 002 的臨時任務拆解文件,已歸檔
|
| 4 |
+
> 下次迭代時將重新生成 `spec/task.md`。所有已完成的任務詳見下方歸檔摘要。
|