annabossler commited on
Commit
38d2ff0
·
verified ·
1 Parent(s): bbeae4b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +64 -50
app.py CHANGED
@@ -9,7 +9,7 @@ from gradio_molecule3d import Molecule3D
9
  from simulation_scripts_orbmol import load_orbmol_model, run_md_simulation, run_relaxation_simulation
10
  import hashlib
11
 
12
- # ==== Configuración Molecule3D (igual que Facebook UMA) ====
13
  DEFAULT_MOLECULAR_REPRESENTATIONS = [
14
  {
15
  "model": 0,
@@ -39,26 +39,46 @@ DEFAULT_MOLECULAR_SETTINGS = {
39
  "disableFog": False,
40
  }
41
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  # ==== OrbMol SPE ====
43
  def predict_molecule(structure_file, task_name, charge=0, spin_multiplicity=1):
44
  """Single Point Energy + fuerzas (OrbMol)"""
45
  try:
46
  calc = load_orbmol_model(task_name)
47
  if not structure_file:
48
- return "Error: Please upload a structure file", "Error"
49
 
50
  file_path = structure_file
51
  if not os.path.exists(file_path):
52
- return f"Error: File not found: {file_path}", "Error"
53
  if os.path.getsize(file_path) == 0:
54
- return f"Error: Empty file: {file_path}", "Error"
55
 
56
  atoms = read(file_path)
57
-
58
- # Solo aplicar charge/spin para OMol
59
  if task_name in ["OMol", "OMol-Direct"]:
60
  atoms.info = {"charge": int(charge), "spin": int(spin_multiplicity)}
61
-
62
  atoms.calc = calc
63
  energy = atoms.get_potential_energy()
64
  forces = atoms.get_forces()
@@ -74,18 +94,20 @@ def predict_molecule(structure_file, task_name, charge=0, spin_multiplicity=1):
74
  max_force = float(np.max(np.linalg.norm(forces, axis=1)))
75
  lines += ["", f"Max Force: {max_force:.4f} eV/Å"]
76
 
77
- return "\n".join(lines), f"Calculation completed with {task_name}"
78
-
 
 
79
  except Exception as e:
80
  import traceback
81
  traceback.print_exc()
82
- return f"Error during calculation: {e}", "Error"
83
 
84
  # ==== Wrappers MD y Relax ====
85
  def md_wrapper(structure_file, task_name, charge, spin, steps, tempK, timestep_fs, ensemble):
86
  try:
87
  if not structure_file:
88
- return ("Error: Please upload a structure file", None, "", "", "")
89
 
90
  traj_path, log_text, script_text, explanation = run_md_simulation(
91
  structure_file,
@@ -100,17 +122,19 @@ def md_wrapper(structure_file, task_name, charge, spin, steps, tempK, timestep_f
100
  )
101
  status = f"MD completed: {int(steps)} steps at {int(tempK)} K ({ensemble})"
102
 
103
- return (status, traj_path, log_text, script_text, explanation)
 
 
104
 
105
  except Exception as e:
106
  import traceback
107
  traceback.print_exc()
108
- return (f"Error: {e}", None, "", "", "")
109
 
110
  def relax_wrapper(structure_file, task_name, steps, fmax, charge, spin, relax_cell):
111
  try:
112
  if not structure_file:
113
- return ("Error: Please upload a structure file", None, "", "", "")
114
 
115
  traj_path, log_text, script_text, explanation = run_relaxation_simulation(
116
  structure_file,
@@ -123,12 +147,14 @@ def relax_wrapper(structure_file, task_name, steps, fmax, charge, spin, relax_ce
123
  )
124
  status = f"Relaxation finished (<={int(steps)} steps, fmax={float(fmax)} eV/Å)"
125
 
126
- return (status, traj_path, log_text, script_text, explanation)
 
 
127
 
128
  except Exception as e:
129
  import traceback
130
  traceback.print_exc()
131
- return (f"Error: {e}", None, "", "", "")
132
 
133
  # ==== UI ====
134
  with gr.Blocks(theme=gr.themes.Ocean(), title="OrbMol Demo") as demo:
@@ -139,7 +165,7 @@ with gr.Blocks(theme=gr.themes.Ocean(), title="OrbMol Demo") as demo:
139
  with gr.Column(scale=2):
140
  gr.Markdown("# OrbMol — Quantum-Accurate Molecular Predictions")
141
  gr.Markdown("**Supported formats:** .xyz, .pdb, .cif, .traj, .mol, .sdf")
142
-
143
  xyz_input = gr.File(
144
  label="Upload Structure File",
145
  file_types=[".xyz", ".pdb", ".cif", ".traj", ".mol", ".sdf"],
@@ -153,23 +179,19 @@ with gr.Blocks(theme=gr.themes.Ocean(), title="OrbMol Demo") as demo:
153
  with gr.Row():
154
  charge_input = gr.Slider(-10, 10, 0, step=1, label="Charge")
155
  spin_input = gr.Slider(1, 11, 1, step=1, label="Spin Multiplicity")
156
-
157
  run_spe = gr.Button("Run OrbMol Prediction", variant="primary")
158
-
159
  with gr.Column(variant="panel", min_width=500):
160
  spe_out = gr.Textbox(label="Energy & Forces", lines=15, interactive=False)
161
  spe_status = gr.Textbox(label="Status", interactive=False)
162
-
163
  spe_viewer = Molecule3D(
164
  label="Input Structure Viewer",
165
  reps=DEFAULT_MOLECULAR_REPRESENTATIONS,
166
- config=DEFAULT_MOLECULAR_SETTINGS,
167
- render=True, # ← activado
168
- inputs=[xyz_input],
169
- value=lambda x: x,
170
- interactive=False
171
  )
172
-
173
  task_name_spe.change(
174
  lambda x: (
175
  gr.update(visible=x in ["OMol", "OMol-Direct"]),
@@ -178,11 +200,11 @@ with gr.Blocks(theme=gr.themes.Ocean(), title="OrbMol Demo") as demo:
178
  [task_name_spe],
179
  [charge_input, spin_input]
180
  )
181
-
182
  run_spe.click(
183
  predict_molecule,
184
  [xyz_input, task_name_spe, charge_input, spin_input],
185
- [spe_out, spe_status]
186
  )
187
 
188
  # -------- MD --------
@@ -190,7 +212,7 @@ with gr.Blocks(theme=gr.themes.Ocean(), title="OrbMol Demo") as demo:
190
  with gr.Row():
191
  with gr.Column(scale=2):
192
  gr.Markdown("## Molecular Dynamics Simulation")
193
-
194
  xyz_md = gr.File(
195
  label="Upload Structure File",
196
  file_types=[".xyz", ".pdb", ".cif", ".traj", ".mol", ".sdf"],
@@ -215,21 +237,17 @@ with gr.Blocks(theme=gr.themes.Ocean(), title="OrbMol Demo") as demo:
215
  with gr.Column(variant="panel", min_width=520):
216
  md_status = gr.Textbox(label="MD Status", interactive=False)
217
  md_traj = gr.File(label="Trajectory (.traj)", interactive=False)
218
-
219
  md_viewer = Molecule3D(
220
  label="MD Result Viewer",
221
  reps=DEFAULT_MOLECULAR_REPRESENTATIONS,
222
- config=DEFAULT_MOLECULAR_SETTINGS,
223
- render=True, # ← activado
224
- inputs=[md_traj],
225
- value=lambda x: x,
226
- interactive=False
227
  )
228
-
229
  md_log = gr.Textbox(label="Log", interactive=False, lines=15)
230
  md_script = gr.Code(label="Reproduction Script", language="python", interactive=False, lines=20)
231
  md_explain = gr.Markdown()
232
-
233
  task_name_md.change(
234
  lambda x: (
235
  gr.update(visible=x in ["OMol", "OMol-Direct"]),
@@ -238,11 +256,11 @@ with gr.Blocks(theme=gr.themes.Ocean(), title="OrbMol Demo") as demo:
238
  [task_name_md],
239
  [charge_md, spin_md]
240
  )
241
-
242
  run_md_btn.click(
243
  md_wrapper,
244
  [xyz_md, task_name_md, charge_md, spin_md, steps_md, temp_md, timestep_md, ensemble_md],
245
- [md_status, md_traj, md_log, md_script, md_explain]
246
  )
247
 
248
  # -------- Relax --------
@@ -250,7 +268,7 @@ with gr.Blocks(theme=gr.themes.Ocean(), title="OrbMol Demo") as demo:
250
  with gr.Row():
251
  with gr.Column(scale=2):
252
  gr.Markdown("## Structure Relaxation/Optimization")
253
-
254
  xyz_rlx = gr.File(
255
  label="Upload Structure File",
256
  file_types=[".xyz", ".pdb", ".cif", ".traj", ".mol", ".sdf"],
@@ -273,17 +291,13 @@ with gr.Blocks(theme=gr.themes.Ocean(), title="OrbMol Demo") as demo:
273
  with gr.Column(variant="panel", min_width=520):
274
  rlx_status = gr.Textbox(label="Status", interactive=False)
275
  rlx_traj = gr.File(label="Trajectory (.traj)", interactive=False)
276
-
277
  rlx_viewer = Molecule3D(
278
  label="Optimized Structure Viewer",
279
  reps=DEFAULT_MOLECULAR_REPRESENTATIONS,
280
- config=DEFAULT_MOLECULAR_SETTINGS,
281
- render=True, # ← activado
282
- inputs=[rlx_traj],
283
- value=lambda x: x,
284
- interactive=False
285
  )
286
-
287
  rlx_log = gr.Textbox(label="Log", interactive=False, lines=15)
288
  rlx_script = gr.Code(label="Reproduction Script", language="python", interactive=False, lines=20)
289
  rlx_explain = gr.Markdown()
@@ -296,12 +310,12 @@ with gr.Blocks(theme=gr.themes.Ocean(), title="OrbMol Demo") as demo:
296
  [task_name_rlx],
297
  [charge_rlx, spin_rlx]
298
  )
299
-
300
  run_rlx_btn.click(
301
  relax_wrapper,
302
  [xyz_rlx, task_name_rlx, steps_rlx, fmax_rlx, charge_rlx, spin_rlx, relax_cell],
303
- [rlx_status, rlx_traj, rlx_log, rlx_script, rlx_explain]
304
  )
305
 
306
  if __name__ == "__main__":
307
- demo.launch(server_name="0.0.0.0", server_port=7860, show_error=True)
 
9
  from simulation_scripts_orbmol import load_orbmol_model, run_md_simulation, run_relaxation_simulation
10
  import hashlib
11
 
12
+ # ==== Configuración Molecule3D ====
13
  DEFAULT_MOLECULAR_REPRESENTATIONS = [
14
  {
15
  "model": 0,
 
39
  "disableFog": False,
40
  }
41
 
42
+ # ==== Conversión a PDB para Molecule3D ====
43
+ def convert_to_pdb_for_viewer(file_path):
44
+ """Convierte cualquier archivo a PDB para Molecule3D"""
45
+ if not file_path or not os.path.exists(file_path):
46
+ return None
47
+
48
+ try:
49
+ atoms = read(file_path)
50
+
51
+ cache_dir = os.path.join(tempfile.gettempdir(), "gradio")
52
+ os.makedirs(cache_dir, exist_ok=True)
53
+
54
+ pdb_path = os.path.join(cache_dir, f"mol_{hashlib.md5(file_path.encode()).hexdigest()[:12]}.pdb")
55
+
56
+ write(pdb_path, atoms, format="proteindatabank")
57
+
58
+ return pdb_path
59
+ except Exception as e:
60
+ print(f"Error converting to PDB: {e}")
61
+ return None
62
+
63
  # ==== OrbMol SPE ====
64
  def predict_molecule(structure_file, task_name, charge=0, spin_multiplicity=1):
65
  """Single Point Energy + fuerzas (OrbMol)"""
66
  try:
67
  calc = load_orbmol_model(task_name)
68
  if not structure_file:
69
+ return "Error: Please upload a structure file", "Error", None
70
 
71
  file_path = structure_file
72
  if not os.path.exists(file_path):
73
+ return f"Error: File not found: {file_path}", "Error", None
74
  if os.path.getsize(file_path) == 0:
75
+ return f"Error: Empty file: {file_path}", "Error", None
76
 
77
  atoms = read(file_path)
78
+
 
79
  if task_name in ["OMol", "OMol-Direct"]:
80
  atoms.info = {"charge": int(charge), "spin": int(spin_multiplicity)}
81
+
82
  atoms.calc = calc
83
  energy = atoms.get_potential_energy()
84
  forces = atoms.get_forces()
 
94
  max_force = float(np.max(np.linalg.norm(forces, axis=1)))
95
  lines += ["", f"Max Force: {max_force:.4f} eV/Å"]
96
 
97
+ pdb_file = convert_to_pdb_for_viewer(file_path)
98
+
99
+ return "\n".join(lines), f"Calculation completed with {task_name}", pdb_file
100
+
101
  except Exception as e:
102
  import traceback
103
  traceback.print_exc()
104
+ return f"Error during calculation: {e}", "Error", None
105
 
106
  # ==== Wrappers MD y Relax ====
107
  def md_wrapper(structure_file, task_name, charge, spin, steps, tempK, timestep_fs, ensemble):
108
  try:
109
  if not structure_file:
110
+ return ("Error: Please upload a structure file", None, "", "", "", None)
111
 
112
  traj_path, log_text, script_text, explanation = run_md_simulation(
113
  structure_file,
 
122
  )
123
  status = f"MD completed: {int(steps)} steps at {int(tempK)} K ({ensemble})"
124
 
125
+ pdb_file = convert_to_pdb_for_viewer(traj_path)
126
+
127
+ return (status, traj_path, log_text, script_text, explanation, pdb_file)
128
 
129
  except Exception as e:
130
  import traceback
131
  traceback.print_exc()
132
+ return (f"Error: {e}", None, "", "", "", None)
133
 
134
  def relax_wrapper(structure_file, task_name, steps, fmax, charge, spin, relax_cell):
135
  try:
136
  if not structure_file:
137
+ return ("Error: Please upload a structure file", None, "", "", "", None)
138
 
139
  traj_path, log_text, script_text, explanation = run_relaxation_simulation(
140
  structure_file,
 
147
  )
148
  status = f"Relaxation finished (<={int(steps)} steps, fmax={float(fmax)} eV/Å)"
149
 
150
+ pdb_file = convert_to_pdb_for_viewer(traj_path)
151
+
152
+ return (status, traj_path, log_text, script_text, explanation, pdb_file)
153
 
154
  except Exception as e:
155
  import traceback
156
  traceback.print_exc()
157
+ return (f"Error: {e}", None, "", "", "", None)
158
 
159
  # ==== UI ====
160
  with gr.Blocks(theme=gr.themes.Ocean(), title="OrbMol Demo") as demo:
 
165
  with gr.Column(scale=2):
166
  gr.Markdown("# OrbMol — Quantum-Accurate Molecular Predictions")
167
  gr.Markdown("**Supported formats:** .xyz, .pdb, .cif, .traj, .mol, .sdf")
168
+
169
  xyz_input = gr.File(
170
  label="Upload Structure File",
171
  file_types=[".xyz", ".pdb", ".cif", ".traj", ".mol", ".sdf"],
 
179
  with gr.Row():
180
  charge_input = gr.Slider(-10, 10, 0, step=1, label="Charge")
181
  spin_input = gr.Slider(1, 11, 1, step=1, label="Spin Multiplicity")
182
+
183
  run_spe = gr.Button("Run OrbMol Prediction", variant="primary")
184
+
185
  with gr.Column(variant="panel", min_width=500):
186
  spe_out = gr.Textbox(label="Energy & Forces", lines=15, interactive=False)
187
  spe_status = gr.Textbox(label="Status", interactive=False)
188
+
189
  spe_viewer = Molecule3D(
190
  label="Input Structure Viewer",
191
  reps=DEFAULT_MOLECULAR_REPRESENTATIONS,
192
+ config=DEFAULT_MOLECULAR_SETTINGS
 
 
 
 
193
  )
194
+
195
  task_name_spe.change(
196
  lambda x: (
197
  gr.update(visible=x in ["OMol", "OMol-Direct"]),
 
200
  [task_name_spe],
201
  [charge_input, spin_input]
202
  )
203
+
204
  run_spe.click(
205
  predict_molecule,
206
  [xyz_input, task_name_spe, charge_input, spin_input],
207
+ [spe_out, spe_status, spe_viewer]
208
  )
209
 
210
  # -------- MD --------
 
212
  with gr.Row():
213
  with gr.Column(scale=2):
214
  gr.Markdown("## Molecular Dynamics Simulation")
215
+
216
  xyz_md = gr.File(
217
  label="Upload Structure File",
218
  file_types=[".xyz", ".pdb", ".cif", ".traj", ".mol", ".sdf"],
 
237
  with gr.Column(variant="panel", min_width=520):
238
  md_status = gr.Textbox(label="MD Status", interactive=False)
239
  md_traj = gr.File(label="Trajectory (.traj)", interactive=False)
240
+
241
  md_viewer = Molecule3D(
242
  label="MD Result Viewer",
243
  reps=DEFAULT_MOLECULAR_REPRESENTATIONS,
244
+ config=DEFAULT_MOLECULAR_SETTINGS
 
 
 
 
245
  )
246
+
247
  md_log = gr.Textbox(label="Log", interactive=False, lines=15)
248
  md_script = gr.Code(label="Reproduction Script", language="python", interactive=False, lines=20)
249
  md_explain = gr.Markdown()
250
+
251
  task_name_md.change(
252
  lambda x: (
253
  gr.update(visible=x in ["OMol", "OMol-Direct"]),
 
256
  [task_name_md],
257
  [charge_md, spin_md]
258
  )
259
+
260
  run_md_btn.click(
261
  md_wrapper,
262
  [xyz_md, task_name_md, charge_md, spin_md, steps_md, temp_md, timestep_md, ensemble_md],
263
+ [md_status, md_traj, md_log, md_script, md_explain, md_viewer]
264
  )
265
 
266
  # -------- Relax --------
 
268
  with gr.Row():
269
  with gr.Column(scale=2):
270
  gr.Markdown("## Structure Relaxation/Optimization")
271
+
272
  xyz_rlx = gr.File(
273
  label="Upload Structure File",
274
  file_types=[".xyz", ".pdb", ".cif", ".traj", ".mol", ".sdf"],
 
291
  with gr.Column(variant="panel", min_width=520):
292
  rlx_status = gr.Textbox(label="Status", interactive=False)
293
  rlx_traj = gr.File(label="Trajectory (.traj)", interactive=False)
294
+
295
  rlx_viewer = Molecule3D(
296
  label="Optimized Structure Viewer",
297
  reps=DEFAULT_MOLECULAR_REPRESENTATIONS,
298
+ config=DEFAULT_MOLECULAR_SETTINGS
 
 
 
 
299
  )
300
+
301
  rlx_log = gr.Textbox(label="Log", interactive=False, lines=15)
302
  rlx_script = gr.Code(label="Reproduction Script", language="python", interactive=False, lines=20)
303
  rlx_explain = gr.Markdown()
 
310
  [task_name_rlx],
311
  [charge_rlx, spin_rlx]
312
  )
313
+
314
  run_rlx_btn.click(
315
  relax_wrapper,
316
  [xyz_rlx, task_name_rlx, steps_rlx, fmax_rlx, charge_rlx, spin_rlx, relax_cell],
317
+ [rlx_status, rlx_traj, rlx_log, rlx_script, rlx_explain, rlx_viewer]
318
  )
319
 
320
  if __name__ == "__main__":
321
+ demo.launch(server_name="0.0.0.0", server_port=7860, show_error=True)