lucl13 commited on
Commit
1fb3d63
·
1 Parent(s): fef6271

merge the settings into the main page and better error handling

Browse files
Files changed (1) hide show
  1. app.py +93 -84
app.py CHANGED
@@ -50,38 +50,29 @@ def get_display_state_name(state_key, state_keys):
50
  else:
51
  return "_".join(state_key.split("_")[:-1])
52
 
53
- def predict_gradio_with_error_handling(
54
- file1,
55
- file2,
56
- pdb_id_input,
57
- pdb_file_input,
58
- centroid_model,
59
- uptake_plots,
60
- auto_vmin_vmax,
61
- vmin,
62
- vmax,
63
- ):
64
- """
65
- Wrapper function that handles errors and returns error information along with results.
66
- """
67
- try:
68
- # Call the original prediction function
69
- results = predict_gradio(
70
- file1, file2, pdb_id_input, pdb_file_input, centroid_model,
71
- uptake_plots, auto_vmin_vmax, vmin, vmax
72
- )
73
- return (*results, "", gr.update(visible=False))
74
-
75
- except Exception as e:
76
-
77
- error_msg = f"Error Type: {type(e).__name__}\n\n"
78
- error_msg += f"Error Message: {str(e)}\n\n"
79
- error_msg += "Full Traceback:\n"
80
- error_msg += traceback.format_exc()
81
-
82
-
83
- empty_results = ("", None, "", None, "", None, "", None, None)
84
- return (*empty_results, error_msg, gr.update(visible=True))
85
 
86
  def predict_gradio(
87
  file1,
@@ -90,21 +81,36 @@ def predict_gradio(
90
  pdb_file_input,
91
  centroid_model,
92
  uptake_plots,
93
- auto_vmin_vmax,
94
  vmin,
95
  vmax,
96
  ):
97
 
98
  print(file1, file2,)
99
- if file2 is None:
100
- input_files = [file1]
101
- else:
102
- input_files = [file1, file2]
 
 
 
 
 
 
 
 
103
 
104
  hdxms_data_list = [ load_HXMS_file(input_file) for input_file in input_files ]
105
  global state_names
106
  state_names = [state.state_name for data in hdxms_data_list for state in data.states]
107
 
 
 
 
 
 
 
 
 
108
 
109
  global output_dir
110
  output_dir = tempfile.mkdtemp()
@@ -147,10 +153,7 @@ def predict_gradio(
147
  if pdb_id_input or pdb_file_input:
148
  pdb_path = load_pdb_data(pdb_id_input, pdb_file_input)
149
  dg_pdb_path = make_BFactorPlot(pdb_path, analysis_objs, output_dir)
150
- if auto_vmin_vmax:
151
- molstar_view_html = get_structure_html(dg_pdb_path, vmin=vmin, vmax=vmax)
152
- else:
153
- molstar_view_html = get_structure_html(dg_pdb_path)
154
  else:
155
  molstar_view_html = None
156
 
@@ -1120,10 +1123,6 @@ def get_colorbar_css(color_list):
1120
  color_stops.append(f"{c} {pct}%")
1121
  return ", ".join(color_stops)
1122
 
1123
- def clear_outputs():
1124
- """Clear all outputs"""
1125
- return "", None, "", None, "", None, "", None, None
1126
-
1127
  GA_ID = os.environ.get("GOOGLE_ANALYTICS_ID", "")
1128
  ga_script = ""
1129
  if GA_ID:
@@ -1139,16 +1138,6 @@ if GA_ID:
1139
 
1140
  with gr.Blocks(
1141
  css="""
1142
- .error-box {
1143
- background-color: #fee !important;
1144
- border-left: 4px solid #dc3545 !important;
1145
- color: #721c24 !important;
1146
- font-family: monospace !important;
1147
- }
1148
- .error-box textarea {
1149
- background-color: #fee !important;
1150
- color: #721c24 !important;
1151
- }
1152
  """,
1153
  head=ga_script
1154
  ) as demo:
@@ -1170,30 +1159,27 @@ with gr.Blocks(
1170
  with gr.Column(scale=1):
1171
  demo_btn1 = gr.Button("Load demo data (mini_protein)",)
1172
  demo_btn2 = gr.Button("Load demo data (ecDHFR)")
1173
-
1174
- with gr.TabItem("Settings"):
1175
- centroid_model = gr.Checkbox(label="Use centroid model", value=False)
1176
- uptake_plots = gr.Checkbox(label="Generate uptake plots", value=False)
1177
-
1178
- with gr.Row():
1179
- auto_vmin_vmax = gr.Checkbox(label="Custom color range", value=False)
1180
- vmin = gr.Slider(minimum=-100, maximum=100, value=0, step=1, label="Colorbar minimum")
1181
- vmax = gr.Slider(minimum=-100, maximum=100, value=50, step=1, label="Colorbar maximum")
 
 
 
 
 
 
 
1182
 
1183
  btn = gr.Button("Run prediction")
1184
 
1185
  gr.Markdown("# Output")
1186
 
1187
- # Error display
1188
- error_box = gr.Textbox(
1189
- label="Error Details",
1190
- lines=10,
1191
- autoscroll=True,
1192
- visible=False,
1193
- elem_classes=["error-box"],
1194
- interactive=False
1195
- )
1196
-
1197
  with gr.Tabs():
1198
  with gr.TabItem("Summary"):
1199
  summary = gr.Textbox(label="Results summary", lines=30, autoscroll=True)
@@ -1235,11 +1221,7 @@ with gr.Blocks(
1235
  zip_file = gr.File(label="Download all results as a ZIP file")
1236
 
1237
  btn.click(
1238
- fn=clear_outputs,
1239
- inputs=[],
1240
- outputs=[summary, log_kex_plot, molstar_view, uptake_gallery, uptake_info, ae_histogram, ae_info, heatmaps, zip_file],
1241
- ).then(
1242
- fn=predict_gradio_with_error_handling,
1243
  inputs=[
1244
  file1,
1245
  file2,
@@ -1247,19 +1229,46 @@ with gr.Blocks(
1247
  pdb_file_input,
1248
  centroid_model,
1249
  uptake_plots,
1250
- auto_vmin_vmax,
1251
  vmin,
1252
  vmax,
1253
  ],
1254
- outputs=[summary, log_kex_plot, molstar_view, uptake_gallery, uptake_info, ae_histogram, ae_info, heatmaps, zip_file, error_box, error_box],
1255
  )
1256
 
1257
- demo_btn1.click(fn=load_demo_data_mini_protein, inputs=[], outputs=[file1, file2, pdb_file_input])
1258
- demo_btn2.click(fn=load_demo_data_ecDHFR, inputs=[], outputs=[file1, file2, pdb_file_input])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1259
 
1260
 
1261
 
1262
  demo.launch(
1263
  share=True,
1264
  debug=False,
1265
- )
 
 
50
  else:
51
  return "_".join(state_key.split("_")[:-1])
52
 
53
+ def resolve_uploaded_file_path(file_obj):
54
+ """Normalize Gradio file input into a filesystem path."""
55
+ if file_obj is None:
56
+ return None
57
+ if isinstance(file_obj, str):
58
+ return file_obj
59
+ file_name = getattr(file_obj, "name", None)
60
+ if isinstance(file_name, str):
61
+ return file_name
62
+ if isinstance(file_obj, dict):
63
+ for key in ("name", "path"):
64
+ value = file_obj.get(key)
65
+ if isinstance(value, str):
66
+ return value
67
+ return None
68
+
69
+ def get_default_structure_color_range(file1, file2):
70
+ """Pick structure coloring defaults from the number of HXMS inputs."""
71
+ has_file1 = resolve_uploaded_file_path(file1) is not None
72
+ has_file2 = resolve_uploaded_file_path(file2) is not None
73
+ if has_file1 and has_file2:
74
+ return -25, 25
75
+ return 0, 50
 
 
 
 
 
 
 
 
 
76
 
77
  def predict_gradio(
78
  file1,
 
81
  pdb_file_input,
82
  centroid_model,
83
  uptake_plots,
 
84
  vmin,
85
  vmax,
86
  ):
87
 
88
  print(file1, file2,)
89
+ input_files = [
90
+ resolve_uploaded_file_path(file_obj)
91
+ for file_obj in (file1, file2)
92
+ ]
93
+ input_files = [path for path in input_files if path]
94
+
95
+ if len(input_files) == 0:
96
+ raise gr.Error("Please upload at least one HXMS file.")
97
+ if vmin is None or vmax is None:
98
+ vmin, vmax = get_default_structure_color_range(file1, file2)
99
+ if vmin >= vmax:
100
+ raise gr.Error("Structure color min must be smaller than structure color max.")
101
 
102
  hdxms_data_list = [ load_HXMS_file(input_file) for input_file in input_files ]
103
  global state_names
104
  state_names = [state.state_name for data in hdxms_data_list for state in data.states]
105
 
106
+ if not centroid_model:
107
+ _all_tps = [tp for data in hdxms_data_list for state in data.states for pep in state.peptides for tp in pep.timepoints if tp.deut_time != np.inf and tp.deut_time != 0.0]
108
+ _envelope_tps = [tp for tp in _all_tps if tp.isotope_envelope is not None and len(tp.isotope_envelope) > 3]
109
+ if len(_envelope_tps) == 0:
110
+ raise gr.Error(
111
+ "No envelope data found in the input file(s). "
112
+ "You may want to use centroid mode or check the input."
113
+ )
114
 
115
  global output_dir
116
  output_dir = tempfile.mkdtemp()
 
153
  if pdb_id_input or pdb_file_input:
154
  pdb_path = load_pdb_data(pdb_id_input, pdb_file_input)
155
  dg_pdb_path = make_BFactorPlot(pdb_path, analysis_objs, output_dir)
156
+ molstar_view_html = get_structure_html(dg_pdb_path, vmin=vmin, vmax=vmax)
 
 
 
157
  else:
158
  molstar_view_html = None
159
 
 
1123
  color_stops.append(f"{c} {pct}%")
1124
  return ", ".join(color_stops)
1125
 
 
 
 
 
1126
  GA_ID = os.environ.get("GOOGLE_ANALYTICS_ID", "")
1127
  ga_script = ""
1128
  if GA_ID:
 
1138
 
1139
  with gr.Blocks(
1140
  css="""
 
 
 
 
 
 
 
 
 
 
1141
  """,
1142
  head=ga_script
1143
  ) as demo:
 
1159
  with gr.Column(scale=1):
1160
  demo_btn1 = gr.Button("Load demo data (mini_protein)",)
1161
  demo_btn2 = gr.Button("Load demo data (ecDHFR)")
1162
+
1163
+ gr.Markdown("### Settings")
1164
+ with gr.Row(equal_height=True):
1165
+ with gr.Column(scale=1, min_width=220):
1166
+ centroid_model = gr.Checkbox(label="Use centroid model", value=False)
1167
+ uptake_plots = gr.Checkbox(label="Generate uptake plots", value=False)
1168
+ with gr.Column(scale=1, min_width=220):
1169
+ with gr.Row():
1170
+ vmin = gr.Number(
1171
+ value=0,
1172
+ label="Structure color min",
1173
+ )
1174
+ vmax = gr.Number(
1175
+ value=50,
1176
+ label="Structure color max",
1177
+ )
1178
 
1179
  btn = gr.Button("Run prediction")
1180
 
1181
  gr.Markdown("# Output")
1182
 
 
 
 
 
 
 
 
 
 
 
1183
  with gr.Tabs():
1184
  with gr.TabItem("Summary"):
1185
  summary = gr.Textbox(label="Results summary", lines=30, autoscroll=True)
 
1221
  zip_file = gr.File(label="Download all results as a ZIP file")
1222
 
1223
  btn.click(
1224
+ fn=predict_gradio,
 
 
 
 
1225
  inputs=[
1226
  file1,
1227
  file2,
 
1229
  pdb_file_input,
1230
  centroid_model,
1231
  uptake_plots,
 
1232
  vmin,
1233
  vmax,
1234
  ],
1235
+ outputs=[summary, log_kex_plot, molstar_view, uptake_gallery, uptake_info, ae_histogram, ae_info, heatmaps, zip_file],
1236
  )
1237
 
1238
+ file1.change(
1239
+ fn=get_default_structure_color_range,
1240
+ inputs=[file1, file2],
1241
+ outputs=[vmin, vmax],
1242
+ )
1243
+ file2.change(
1244
+ fn=get_default_structure_color_range,
1245
+ inputs=[file1, file2],
1246
+ outputs=[vmin, vmax],
1247
+ )
1248
+
1249
+ demo_btn1.click(
1250
+ fn=load_demo_data_mini_protein,
1251
+ inputs=[],
1252
+ outputs=[file1, file2, pdb_file_input],
1253
+ ).then(
1254
+ fn=get_default_structure_color_range,
1255
+ inputs=[file1, file2],
1256
+ outputs=[vmin, vmax],
1257
+ )
1258
+ demo_btn2.click(
1259
+ fn=load_demo_data_ecDHFR,
1260
+ inputs=[],
1261
+ outputs=[file1, file2, pdb_file_input],
1262
+ ).then(
1263
+ fn=get_default_structure_color_range,
1264
+ inputs=[file1, file2],
1265
+ outputs=[vmin, vmax],
1266
+ )
1267
 
1268
 
1269
 
1270
  demo.launch(
1271
  share=True,
1272
  debug=False,
1273
+ show_error=True,
1274
+ )