jimmy60504 commited on
Commit
285c304
·
1 Parent(s): 26071fc

update UI to improve Ground Truth image handling and adjust height for better alignment

Browse files
Files changed (1) hide show
  1. app.py +42 -11
app.py CHANGED
@@ -634,7 +634,7 @@ def create_intensity_map(pga_list, target_names, epicenter_lat=None, epicenter_l
634
  zoom_start=7,
635
  tiles='OpenStreetMap',
636
  width='100%',
637
- height='600px' # 設定固定高度,與 Ground Truth 圖片匹配
638
  )
639
 
640
  # 如果有震央位置,標記震央
@@ -759,6 +759,16 @@ def load_ground_truth_image(event_name):
759
  return None
760
 
761
 
 
 
 
 
 
 
 
 
 
 
762
  def create_input_station_map(selected_stations, epicenter_lat, epicenter_lon):
763
  """創建輸入測站分布地圖:顯示所有測站 + 突顯被選中的 25 個"""
764
  import folium
@@ -770,7 +780,7 @@ def create_input_station_map(selected_stations, epicenter_lat, epicenter_lon):
770
  zoom_start=8,
771
  tiles='OpenStreetMap',
772
  width='100%',
773
- height='500px'
774
  )
775
 
776
  # 建立被選中測站的 set(用於快速查詢)
@@ -882,9 +892,12 @@ def create_input_station_map(selected_stations, epicenter_lat, epicenter_lon):
882
  return m
883
 
884
 
885
- def load_and_display_waveform(event_name, start_time, end_time, epicenter_lon, epicenter_lat):
886
  """載入並顯示波形,讓使用者確認範圍"""
887
  try:
 
 
 
888
  # 1. 載入完整的 mseed 檔案
889
  logger.info(f"載入地震事件: {event_name}")
890
  st = load_waveform(event_name)
@@ -905,7 +918,8 @@ def load_and_display_waveform(event_name, start_time, end_time, epicenter_lon, e
905
  station_map_html = station_map._repr_html_()
906
 
907
  info_text = f"✅ 已載入波形資料\n"
908
- info_text += f"選取時間範圍: {start_time:.1f} - {end_time:.1f} 秒\n"
 
909
  info_text += f"震央位置: ({epicenter_lon:.4f}, {epicenter_lat:.4f})\n"
910
  info_text += f"選擇了 {len(selected_stations)} 個最近的測站\n"
911
  info_text += f"請確認波形範圍後,點擊「執行預測」按鈕"
@@ -920,9 +934,12 @@ def load_and_display_waveform(event_name, start_time, end_time, epicenter_lon, e
920
  return None, None, f"錯誤: {str(e)}", gr.update(interactive=False)
921
 
922
 
923
- def predict_intensity(event_name, start_time, end_time, epicenter_lon, epicenter_lat):
924
  """執行震度預測"""
925
  try:
 
 
 
926
  # 1. 載入完整的 mseed 檔案
927
  logger.info(f"載入地震事件: {event_name}")
928
  st = load_waveform(event_name)
@@ -1018,9 +1035,11 @@ def predict_intensity(event_name, start_time, end_time, epicenter_lon, epicenter
1018
  # 10. 統計資訊
1019
  max_intensity = max([calculate_intensity(pga, label=True) for pga in pga_list])
1020
  stats = f"✅ 預測完成!\n"
1021
- stats += f"選取時間範圍: {start_time:.1f} - {end_time:.1f} 秒\n"
 
1022
  stats += f"震央位置: ({epicenter_lon:.4f}, {epicenter_lat:.4f})\n"
1023
  stats += f"使用測站數: {len(waveforms)} / 25\n"
 
1024
  stats += f"預測最大震度: {max_intensity}"
1025
 
1026
  logger.info("預測完成!")
@@ -1066,8 +1085,8 @@ with gr.Blocks(title="TTSAM 震度預測系統") as demo:
1066
  )
1067
 
1068
  with gr.Row():
1069
- start_slider = gr.Slider(0, 300, value=0, step=1, label="始時間 (秒)")
1070
- end_slider = gr.Slider(0, 300, value=30, step=1, label="結束時間 (秒)")
1071
 
1072
  gr.Markdown("### 震央位置")
1073
  with gr.Row():
@@ -1095,7 +1114,12 @@ with gr.Blocks(title="TTSAM 震度預測系統") as demo:
1095
  # 左下:Ground Truth
1096
  with gr.Column(scale=1):
1097
  gr.Markdown("## Ground Truth 震度分布")
1098
- ground_truth_image = gr.Image(label="實際觀測震度", type="filepath", height=600)
 
 
 
 
 
1099
 
1100
  # 右下:預測震度地圖
1101
  with gr.Column(scale=1):
@@ -1103,17 +1127,24 @@ with gr.Blocks(title="TTSAM 震度預測系統") as demo:
1103
  intensity_map = gr.HTML(label="互動式震度地圖", elem_id="intensity_map")
1104
 
1105
  # 綁定事件
 
 
 
 
 
 
 
1106
  # 第一步:載入波形
1107
  load_waveform_btn.click(
1108
  fn=load_and_display_waveform,
1109
- inputs=[event_dropdown, start_slider, end_slider, epicenter_lon_input, epicenter_lat_input],
1110
  outputs=[input_station_map, waveform_plot, info_output, predict_btn]
1111
  )
1112
 
1113
  # 第二步:執行預測
1114
  predict_btn.click(
1115
  fn=predict_intensity,
1116
- inputs=[event_dropdown, start_slider, end_slider, epicenter_lon_input, epicenter_lat_input],
1117
  outputs=[ground_truth_image, intensity_map, stats_output]
1118
  )
1119
 
 
634
  zoom_start=7,
635
  tiles='OpenStreetMap',
636
  width='100%',
637
+ height='800px' # 設定固定高度 800,與 Ground Truth 圖片匹配
638
  )
639
 
640
  # 如果有震央位置,標記震央
 
759
  return None
760
 
761
 
762
+ def on_event_select(event_name):
763
+ """當選擇事件時立即載入 Ground Truth 圖片"""
764
+ ground_truth_path = load_ground_truth_image(event_name)
765
+ if ground_truth_path:
766
+ return ground_truth_path
767
+ else:
768
+ # 如果找不到圖片,返回 None(Gradio 會顯示空白)
769
+ return None
770
+
771
+
772
  def create_input_station_map(selected_stations, epicenter_lat, epicenter_lon):
773
  """創建輸入測站分布地圖:顯示所有測站 + 突顯被選中的 25 個"""
774
  import folium
 
780
  zoom_start=8,
781
  tiles='OpenStreetMap',
782
  width='100%',
783
+ height='800px'
784
  )
785
 
786
  # 建立被選中測站的 set(用於快速查詢)
 
892
  return m
893
 
894
 
895
+ def load_and_display_waveform(event_name, start_time, duration, epicenter_lon, epicenter_lat):
896
  """載入並顯示波形,讓使用者確認範圍"""
897
  try:
898
+ # 計算結束時間
899
+ end_time = start_time + duration
900
+
901
  # 1. 載入完整的 mseed 檔案
902
  logger.info(f"載入地震事件: {event_name}")
903
  st = load_waveform(event_name)
 
918
  station_map_html = station_map._repr_html_()
919
 
920
  info_text = f"✅ 已載入波形資料\n"
921
+ info_text += f"開始時間: {start_time:.1f} 秒\n"
922
+ info_text += f"時間長度: {duration:.1f} 秒 ({start_time:.1f} - {end_time:.1f})\n"
923
  info_text += f"震央位置: ({epicenter_lon:.4f}, {epicenter_lat:.4f})\n"
924
  info_text += f"選擇了 {len(selected_stations)} 個最近的測站\n"
925
  info_text += f"請確認波形範圍後,點擊「執行預測」按鈕"
 
934
  return None, None, f"錯誤: {str(e)}", gr.update(interactive=False)
935
 
936
 
937
+ def predict_intensity(event_name, start_time, duration, epicenter_lon, epicenter_lat):
938
  """執行震度預測"""
939
  try:
940
+ # 計算結束時間
941
+ end_time = start_time + duration
942
+
943
  # 1. 載入完整的 mseed 檔案
944
  logger.info(f"載入地震事件: {event_name}")
945
  st = load_waveform(event_name)
 
1035
  # 10. 統計資訊
1036
  max_intensity = max([calculate_intensity(pga, label=True) for pga in pga_list])
1037
  stats = f"✅ 預測完成!\n"
1038
+ stats += f"開始時間: {start_time:.1f} 秒\n"
1039
+ stats += f"時間長度: {duration:.1f} 秒 ({start_time:.1f} - {end_time:.1f})\n"
1040
  stats += f"震央位置: ({epicenter_lon:.4f}, {epicenter_lat:.4f})\n"
1041
  stats += f"使用測站數: {len(waveforms)} / 25\n"
1042
+ stats += f"預測目標點數: {len(all_target_names)}\n"
1043
  stats += f"預測最大震度: {max_intensity}"
1044
 
1045
  logger.info("預測完成!")
 
1085
  )
1086
 
1087
  with gr.Row():
1088
+ start_slider = gr.Slider(0, 300, value=0, step=1, label="始時間 (秒)")
1089
+ duration_slider = gr.Slider(1, 60, value=30, step=1, label="時間長度 (秒)")
1090
 
1091
  gr.Markdown("### 震央位置")
1092
  with gr.Row():
 
1114
  # 左下:Ground Truth
1115
  with gr.Column(scale=1):
1116
  gr.Markdown("## Ground Truth 震度分布")
1117
+ ground_truth_image = gr.Image(
1118
+ label="實際觀測震度",
1119
+ type="filepath",
1120
+ height=800,
1121
+ value=load_ground_truth_image(list(EARTHQUAKE_EVENTS.keys())[0]) # 初始載入第一個事件的 Ground Truth
1122
+ )
1123
 
1124
  # 右下:預測震度地圖
1125
  with gr.Column(scale=1):
 
1127
  intensity_map = gr.HTML(label="互動式震度地圖", elem_id="intensity_map")
1128
 
1129
  # 綁定事件
1130
+ # 第零步:選擇事件時立即載入 Ground Truth
1131
+ event_dropdown.change(
1132
+ fn=on_event_select,
1133
+ inputs=[event_dropdown],
1134
+ outputs=[ground_truth_image]
1135
+ )
1136
+
1137
  # 第一步:載入波形
1138
  load_waveform_btn.click(
1139
  fn=load_and_display_waveform,
1140
+ inputs=[event_dropdown, start_slider, duration_slider, epicenter_lon_input, epicenter_lat_input],
1141
  outputs=[input_station_map, waveform_plot, info_output, predict_btn]
1142
  )
1143
 
1144
  # 第二步:執行預測
1145
  predict_btn.click(
1146
  fn=predict_intensity,
1147
+ inputs=[event_dropdown, start_slider, duration_slider, epicenter_lon_input, epicenter_lat_input],
1148
  outputs=[ground_truth_image, intensity_map, stats_output]
1149
  )
1150