annabossler commited on
Commit
0fc2a04
Β·
verified Β·
1 Parent(s): bfe7cbb

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +43 -39
app.py CHANGED
@@ -10,12 +10,12 @@ from ase.optimize import LBFGS
10
  from ase.md.verlet import VelocityVerlet
11
  from ase.md.velocitydistribution import MaxwellBoltzmannDistribution
12
  from ase.io.trajectory import Trajectory
13
-
14
  import py3Dmol
15
 
16
  from orb_models.forcefield import pretrained
17
  from orb_models.forcefield.calculator import ORBCalculator
18
 
 
19
  # -----------------------------
20
  # Global OrbMol model
21
  # -----------------------------
@@ -26,18 +26,18 @@ def load_orbmol_model():
26
  global model_calc
27
  if model_calc is None:
28
  try:
29
- print("Loading OrbMol model...")
30
  orbff = pretrained.orb_v3_conservative_inf_omat(
31
  device="cpu",
32
  precision="float32-high"
33
  )
34
  model_calc = ORBCalculator(orbff, device="cpu")
35
- print("βœ… OrbMol model loaded successfully")
36
  except Exception as e:
37
- print(f"❌ Error loading model: {e}")
38
  model_calc = None
39
  return model_calc
40
 
 
41
  # -----------------------------
42
  # Single-point calculation
43
  # -----------------------------
@@ -45,10 +45,10 @@ def predict_molecule(xyz_content, charge=0, spin_multiplicity=1):
45
  try:
46
  calc = load_orbmol_model()
47
  if calc is None:
48
- return "❌ Error: Could not load OrbMol model", ""
49
 
50
  if not xyz_content.strip():
51
- return "❌ Error: Please enter XYZ coordinates", ""
52
 
53
  with tempfile.NamedTemporaryFile(mode='w', suffix='.xyz', delete=False) as f:
54
  f.write(xyz_content)
@@ -61,20 +61,21 @@ def predict_molecule(xyz_content, charge=0, spin_multiplicity=1):
61
  energy = atoms.get_potential_energy()
62
  forces = atoms.get_forces()
63
 
64
- result = f"πŸ”‹ **Total Energy**: {energy:.6f} eV\n\n⚑ **Atomic Forces**:\n"
65
  for i, f in enumerate(forces):
66
  result += f"Atom {i+1}: [{f[0]:.4f}, {f[1]:.4f}, {f[2]:.4f}] eV/Γ…\n"
67
 
68
  max_force = np.max(np.linalg.norm(forces, axis=1))
69
- result += f"\nπŸ“Š **Max Force**: {max_force:.4f} eV/Γ…"
70
 
71
  os.unlink(xyz_file)
72
- return result, "βœ… Calculation completed with OrbMol"
73
  except Exception as e:
74
- return f"❌ Error during calculation: {str(e)}", "Error"
 
75
 
76
  # -----------------------------
77
- # Trajectory β†’ HTML for Gradio
78
  # -----------------------------
79
  def traj_to_html(traj_file):
80
  traj = Trajectory(traj_file)
@@ -89,7 +90,8 @@ def traj_to_html(traj_file):
89
  view.setStyle({"stick": {}})
90
  view.zoomTo()
91
  view.animate({"loop": "forward"})
92
- return view.render() # βœ… en Gradio funciona mejor que _make_html()
 
93
 
94
  # -----------------------------
95
  # MD simulation
@@ -98,10 +100,10 @@ def run_md(xyz_content, charge=0, spin_multiplicity=1, steps=100, temperature=30
98
  try:
99
  calc = load_orbmol_model()
100
  if calc is None:
101
- return "❌ Error: Could not load OrbMol model", ""
102
 
103
  if not xyz_content.strip():
104
- return "❌ Error: Please enter XYZ coordinates", ""
105
 
106
  with tempfile.NamedTemporaryFile(mode='w', suffix='.xyz', delete=False) as f:
107
  f.write(xyz_content)
@@ -111,28 +113,27 @@ def run_md(xyz_content, charge=0, spin_multiplicity=1, steps=100, temperature=30
111
  atoms.info = {"charge": int(charge), "spin": int(spin_multiplicity)}
112
  atoms.calc = calc
113
 
114
- # Pre-relax
115
  opt = LBFGS(atoms)
116
  opt.run(fmax=0.05, steps=20)
117
 
118
  # Initialize velocities
119
  MaxwellBoltzmannDistribution(atoms, temperature_K=2 * temperature)
120
 
121
- # MD setup
122
  dyn = VelocityVerlet(atoms, timestep=timestep * units.fs)
123
-
124
  traj_file = tempfile.NamedTemporaryFile(suffix=".traj", delete=False)
125
  traj = Trajectory(traj_file.name, "w", atoms)
126
  dyn.attach(traj.write, interval=1)
127
-
128
  dyn.run(steps)
129
 
130
  html = traj_to_html(traj_file.name)
131
 
132
  os.unlink(xyz_file)
133
- return f"βœ… MD completed: {steps} steps at {temperature} K", html
134
  except Exception as e:
135
- return f"❌ Error during MD simulation: {str(e)}", ""
 
136
 
137
  # -----------------------------
138
  # Examples
@@ -142,13 +143,11 @@ examples = [
142
  Hydrogen molecule
143
  H 0.0 0.0 0.0
144
  H 0.0 0.0 0.74""", 0, 1],
145
-
146
  ["""3
147
  Water molecule
148
  O 0.0000 0.0000 0.0000
149
  H 0.7571 0.0000 0.5864
150
  H -0.7571 0.0000 0.5864""", 0, 1],
151
-
152
  ["""5
153
  Methane
154
  C 0.0000 0.0000 0.0000
@@ -158,23 +157,22 @@ H -0.3630 -0.5133 0.8887
158
  H -0.3630 -0.5133 -0.8887""", 0, 1]
159
  ]
160
 
 
161
  # -----------------------------
162
  # Gradio UI
163
  # -----------------------------
164
- with gr.Blocks(theme=gr.themes.Ocean(), title="OrbMol + MD Demo") as demo:
 
165
  with gr.Tab("Single Point Energy"):
166
  with gr.Row():
167
  with gr.Column(scale=2):
168
  with gr.Column(variant="panel"):
169
  gr.Markdown("# OrbMol Demo - Quantum-Accurate Molecular Predictions")
170
- xyz_input = gr.Textbox(
171
- label="XYZ Coordinates", lines=12,
172
- placeholder="Paste XYZ here"
173
- )
174
  with gr.Row():
175
  charge_input = gr.Slider(value=0, label="Charge", minimum=-10, maximum=10, step=1)
176
  spin_input = gr.Slider(value=1, maximum=11, minimum=1, step=1, label="Spin Multiplicity")
177
- run_btn = gr.Button("Run OrbMol Prediction", variant="primary", size="lg")
178
  with gr.Column(variant="panel", min_width=500):
179
  gr.Markdown("## Results")
180
  results_output = gr.Textbox(label="Energy & Forces", lines=15, interactive=False)
@@ -182,29 +180,35 @@ with gr.Blocks(theme=gr.themes.Ocean(), title="OrbMol + MD Demo") as demo:
182
 
183
  gr.Examples(examples=examples, inputs=[xyz_input, charge_input, spin_input])
184
 
185
- run_btn.click(
186
  predict_molecule,
187
  inputs=[xyz_input, charge_input, spin_input],
188
  outputs=[results_output, status_output]
189
  )
190
 
191
  with gr.Tab("Molecular Dynamics"):
192
- xyz_input_md = gr.Textbox(label="XYZ Coordinates", lines=12)
193
- charge_input_md = gr.Slider(value=0, minimum=-10, maximum=10, step=1, label="Charge")
194
- spin_input_md = gr.Slider(value=1, minimum=1, maximum=11, step=1, label="Spin Multiplicity")
195
- steps_input = gr.Slider(value=100, minimum=10, maximum=1000, step=10, label="Steps")
196
- temp_input = gr.Slider(value=300, minimum=10, maximum=1000, step=10, label="Temperature (K)")
197
- timestep_input = gr.Slider(value=1.0, minimum=0.1, maximum=5.0, step=0.1, label="Timestep (fs)")
198
- run_md_btn = gr.Button("Run MD Simulation", variant="primary")
199
- md_status = gr.Textbox(label="MD Status", lines=2)
200
- md_view = gr.HTML()
 
 
 
 
 
201
  run_md_btn.click(
202
  run_md,
203
  inputs=[xyz_input_md, charge_input_md, spin_input_md, steps_input, temp_input, timestep_input],
204
  outputs=[md_status, md_view],
205
  )
206
 
207
- print("πŸš€ Starting OrbMol model loading...")
 
208
  load_orbmol_model()
209
 
210
  if __name__ == "__main__":
 
10
  from ase.md.verlet import VelocityVerlet
11
  from ase.md.velocitydistribution import MaxwellBoltzmannDistribution
12
  from ase.io.trajectory import Trajectory
 
13
  import py3Dmol
14
 
15
  from orb_models.forcefield import pretrained
16
  from orb_models.forcefield.calculator import ORBCalculator
17
 
18
+
19
  # -----------------------------
20
  # Global OrbMol model
21
  # -----------------------------
 
26
  global model_calc
27
  if model_calc is None:
28
  try:
 
29
  orbff = pretrained.orb_v3_conservative_inf_omat(
30
  device="cpu",
31
  precision="float32-high"
32
  )
33
  model_calc = ORBCalculator(orbff, device="cpu")
34
+ print("OrbMol model loaded successfully")
35
  except Exception as e:
36
+ print(f"Error loading OrbMol model: {e}")
37
  model_calc = None
38
  return model_calc
39
 
40
+
41
  # -----------------------------
42
  # Single-point calculation
43
  # -----------------------------
 
45
  try:
46
  calc = load_orbmol_model()
47
  if calc is None:
48
+ return "Error: Could not load OrbMol model", ""
49
 
50
  if not xyz_content.strip():
51
+ return "Error: Please enter XYZ coordinates", ""
52
 
53
  with tempfile.NamedTemporaryFile(mode='w', suffix='.xyz', delete=False) as f:
54
  f.write(xyz_content)
 
61
  energy = atoms.get_potential_energy()
62
  forces = atoms.get_forces()
63
 
64
+ result = f"Total Energy: {energy:.6f} eV\n\nAtomic Forces:\n"
65
  for i, f in enumerate(forces):
66
  result += f"Atom {i+1}: [{f[0]:.4f}, {f[1]:.4f}, {f[2]:.4f}] eV/Γ…\n"
67
 
68
  max_force = np.max(np.linalg.norm(forces, axis=1))
69
+ result += f"\nMax Force: {max_force:.4f} eV/Γ…"
70
 
71
  os.unlink(xyz_file)
72
+ return result, "Calculation completed with OrbMol"
73
  except Exception as e:
74
+ return f"Error during calculation: {str(e)}", "Error"
75
+
76
 
77
  # -----------------------------
78
+ # Trajectory β†’ HTML
79
  # -----------------------------
80
  def traj_to_html(traj_file):
81
  traj = Trajectory(traj_file)
 
90
  view.setStyle({"stick": {}})
91
  view.zoomTo()
92
  view.animate({"loop": "forward"})
93
+ return view.render()
94
+
95
 
96
  # -----------------------------
97
  # MD simulation
 
100
  try:
101
  calc = load_orbmol_model()
102
  if calc is None:
103
+ return "Error: Could not load OrbMol model", ""
104
 
105
  if not xyz_content.strip():
106
+ return "Error: Please enter XYZ coordinates", ""
107
 
108
  with tempfile.NamedTemporaryFile(mode='w', suffix='.xyz', delete=False) as f:
109
  f.write(xyz_content)
 
113
  atoms.info = {"charge": int(charge), "spin": int(spin_multiplicity)}
114
  atoms.calc = calc
115
 
116
+ # Pre-relaxation
117
  opt = LBFGS(atoms)
118
  opt.run(fmax=0.05, steps=20)
119
 
120
  # Initialize velocities
121
  MaxwellBoltzmannDistribution(atoms, temperature_K=2 * temperature)
122
 
123
+ # Run MD
124
  dyn = VelocityVerlet(atoms, timestep=timestep * units.fs)
 
125
  traj_file = tempfile.NamedTemporaryFile(suffix=".traj", delete=False)
126
  traj = Trajectory(traj_file.name, "w", atoms)
127
  dyn.attach(traj.write, interval=1)
 
128
  dyn.run(steps)
129
 
130
  html = traj_to_html(traj_file.name)
131
 
132
  os.unlink(xyz_file)
133
+ return f"MD completed: {steps} steps at {temperature} K", html
134
  except Exception as e:
135
+ return f"Error during MD simulation: {str(e)}", ""
136
+
137
 
138
  # -----------------------------
139
  # Examples
 
143
  Hydrogen molecule
144
  H 0.0 0.0 0.0
145
  H 0.0 0.0 0.74""", 0, 1],
 
146
  ["""3
147
  Water molecule
148
  O 0.0000 0.0000 0.0000
149
  H 0.7571 0.0000 0.5864
150
  H -0.7571 0.0000 0.5864""", 0, 1],
 
151
  ["""5
152
  Methane
153
  C 0.0000 0.0000 0.0000
 
157
  H -0.3630 -0.5133 -0.8887""", 0, 1]
158
  ]
159
 
160
+
161
  # -----------------------------
162
  # Gradio UI
163
  # -----------------------------
164
+ with gr.Blocks(theme=gr.themes.Ocean(), title="OrbMol Demo") as demo:
165
+
166
  with gr.Tab("Single Point Energy"):
167
  with gr.Row():
168
  with gr.Column(scale=2):
169
  with gr.Column(variant="panel"):
170
  gr.Markdown("# OrbMol Demo - Quantum-Accurate Molecular Predictions")
171
+ xyz_input = gr.Textbox(label="XYZ Coordinates", lines=12, placeholder="Paste XYZ here")
 
 
 
172
  with gr.Row():
173
  charge_input = gr.Slider(value=0, label="Charge", minimum=-10, maximum=10, step=1)
174
  spin_input = gr.Slider(value=1, maximum=11, minimum=1, step=1, label="Spin Multiplicity")
175
+ predict_btn = gr.Button("Run OrbMol Prediction", variant="primary", size="lg")
176
  with gr.Column(variant="panel", min_width=500):
177
  gr.Markdown("## Results")
178
  results_output = gr.Textbox(label="Energy & Forces", lines=15, interactive=False)
 
180
 
181
  gr.Examples(examples=examples, inputs=[xyz_input, charge_input, spin_input])
182
 
183
+ predict_btn.click(
184
  predict_molecule,
185
  inputs=[xyz_input, charge_input, spin_input],
186
  outputs=[results_output, status_output]
187
  )
188
 
189
  with gr.Tab("Molecular Dynamics"):
190
+ with gr.Row():
191
+ with gr.Column(scale=2):
192
+ xyz_input_md = gr.Textbox(label="XYZ Coordinates", lines=12)
193
+ charge_input_md = gr.Slider(value=0, minimum=-10, maximum=10, step=1, label="Charge")
194
+ spin_input_md = gr.Slider(value=1, minimum=1, maximum=11, step=1, label="Spin Multiplicity")
195
+ steps_input = gr.Slider(value=100, minimum=10, maximum=1000, step=10, label="Steps")
196
+ temp_input = gr.Slider(value=300, minimum=10, maximum=1000, step=10, label="Temperature (K)")
197
+ timestep_input = gr.Slider(value=1.0, minimum=0.1, maximum=5.0, step=0.1, label="Timestep (fs)")
198
+ run_md_btn = gr.Button("Run MD Simulation", variant="primary")
199
+ md_status = gr.Textbox(label="MD Status", lines=2)
200
+ with gr.Column(scale=1, variant="panel"):
201
+ gr.Markdown("## MD Visualization")
202
+ md_view = gr.HTML()
203
+
204
  run_md_btn.click(
205
  run_md,
206
  inputs=[xyz_input_md, charge_input_md, spin_input_md, steps_input, temp_input, timestep_input],
207
  outputs=[md_status, md_view],
208
  )
209
 
210
+
211
+ print("Starting OrbMol model loading...")
212
  load_orbmol_model()
213
 
214
  if __name__ == "__main__":