annabossler commited on
Commit
427fd9c
Β·
verified Β·
1 Parent(s): 789e0e7

Create app.py

Browse files

app.py based on UMA

Files changed (1) hide show
  1. app.py +219 -0
app.py ADDED
@@ -0,0 +1,219 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import torch
3
+ import numpy as np
4
+ from ase import Atoms
5
+ from ase.io import read, write
6
+ import tempfile
7
+ import os
8
+ from orb_models.forcefield import pretrained
9
+ from orb_models.forcefield.calculator import ORBCalculator
10
+
11
+ # Global variable for the model
12
+ model_calc = None
13
+
14
+ def load_orbmol_model():
15
+ """Load OrbMol model once"""
16
+ global model_calc
17
+ if model_calc is None:
18
+ try:
19
+ print("Loading OrbMol model...")
20
+ orbff = pretrained.orb_v3_conservative_inf_omat(
21
+ device="cpu",
22
+ precision="float32-high"
23
+ )
24
+ model_calc = ORBCalculator(orbff, device="cpu")
25
+ print("βœ… OrbMol model loaded successfully")
26
+ except Exception as e:
27
+ print(f"❌ Error loading model: {e}")
28
+ model_calc = None
29
+ return model_calc
30
+
31
+ def predict_molecule(xyz_content, charge=0, spin_multiplicity=1):
32
+ """
33
+ Main function: XYZ β†’ OrbMol β†’ Results
34
+ """
35
+ try:
36
+ # Load model
37
+ calc = load_orbmol_model()
38
+ if calc is None:
39
+ return "❌ Error: Could not load OrbMol model", ""
40
+
41
+ if not xyz_content.strip():
42
+ return "❌ Error: Please enter XYZ coordinates", ""
43
+
44
+ # Create temporary file with XYZ
45
+ with tempfile.NamedTemporaryFile(mode='w', suffix='.xyz', delete=False) as f:
46
+ f.write(xyz_content)
47
+ xyz_file = f.name
48
+
49
+ # Read molecular structure
50
+ atoms = read(xyz_file)
51
+
52
+ # Configure charge and spin (IMPORTANT for OrbMol!)
53
+ atoms.info = {
54
+ "charge": int(charge),
55
+ "spin": int(spin_multiplicity)
56
+ }
57
+
58
+ # Assign OrbMol calculator
59
+ atoms.calc = calc
60
+
61
+ # Make the prediction!
62
+ energy = atoms.get_potential_energy() # In eV
63
+ forces = atoms.get_forces() # In eV/Γ…
64
+
65
+ # Format results nicely
66
+ result = f"""
67
+ πŸ”‹ **Total Energy**: {energy:.6f} eV
68
+
69
+ ⚑ **Atomic Forces**:
70
+ """
71
+
72
+ for i, force in enumerate(forces):
73
+ result += f"Atom {i+1}: [{force[0]:.4f}, {force[1]:.4f}, {force[2]:.4f}] eV/Γ…\n"
74
+
75
+ # Additional statistics
76
+ max_force = np.max(np.linalg.norm(forces, axis=1))
77
+ result += f"\nπŸ“Š **Max Force**: {max_force:.4f} eV/Γ…"
78
+
79
+ # Clean up temporary file
80
+ os.unlink(xyz_file)
81
+
82
+ return result, "βœ… Calculation completed with OrbMol"
83
+
84
+ except Exception as e:
85
+ return f"❌ Error during calculation: {str(e)}", "Error"
86
+
87
+ # Predefined examples
88
+ examples = [
89
+ ["""2
90
+ Hydrogen molecule
91
+ H 0.0 0.0 0.0
92
+ H 0.0 0.0 0.74""", 0, 1],
93
+
94
+ ["""3
95
+ Water molecule
96
+ O 0.0000 0.0000 0.0000
97
+ H 0.7571 0.0000 0.5864
98
+ H -0.7571 0.0000 0.5864""", 0, 1],
99
+
100
+ ["""4
101
+ Methane
102
+ C 0.0000 0.0000 0.0000
103
+ H 1.0890 0.0000 0.0000
104
+ H -0.3630 1.0267 0.0000
105
+ H -0.3630 -0.5133 0.8887
106
+ H -0.3630 -0.5133 -0.8887""", 0, 1]
107
+ ]
108
+
109
+ # Gradio interface - using FAIR Chem UMA style
110
+ with gr.Blocks(theme=gr.themes.Ocean(), title="OrbMol Demo") as demo:
111
+
112
+ with gr.Row():
113
+ with gr.Column(scale=2):
114
+ with gr.Column(variant="panel"):
115
+ gr.Markdown("# OrbMol Demo - Quantum-Accurate Molecular Predictions")
116
+
117
+ gr.Markdown("""
118
+ **OrbMol** is a neural network potential trained on the **OMol25** dataset (100M+ high-accuracy DFT calculations).
119
+
120
+ Predicts **energies** and **forces** with quantum accuracy, optimized for:
121
+ * 🧬 Biomolecules
122
+ * βš—οΈ Metal complexes
123
+ * πŸ”‹ Electrolytes
124
+ """)
125
+
126
+ gr.Markdown("## Simulation inputs")
127
+
128
+ with gr.Column(variant="panel"):
129
+ gr.Markdown("### Input molecular structure")
130
+
131
+ xyz_input = gr.Textbox(
132
+ label="XYZ Coordinates",
133
+ placeholder="""3
134
+ Water molecule
135
+ O 0.0000 0.0000 0.0000
136
+ H 0.7571 0.0000 0.5864
137
+ H -0.7571 0.0000 0.5864""",
138
+ lines=12,
139
+ info="Paste XYZ coordinates of your molecule here"
140
+ )
141
+
142
+ gr.Markdown("OMol-specific settings for total charge and spin multiplicity")
143
+ with gr.Row():
144
+ charge_input = gr.Slider(
145
+ value=0, label="Total Charge", minimum=-10, maximum=10, step=1
146
+ )
147
+ spin_input = gr.Slider(
148
+ value=1, maximum=11, minimum=1, step=1, label="Spin Multiplicity"
149
+ )
150
+
151
+ predict_btn = gr.Button("Run OrbMol Prediction", variant="primary", size="lg")
152
+
153
+ with gr.Column(variant="panel", elem_id="results", min_width=500):
154
+ gr.Markdown("## OrbMol Prediction Results")
155
+
156
+ results_output = gr.Textbox(
157
+ label="Energy & Forces",
158
+ lines=15,
159
+ interactive=False,
160
+ info="OrbMol energy and force predictions"
161
+ )
162
+
163
+ status_output = gr.Textbox(
164
+ label="Status",
165
+ interactive=False,
166
+ max_lines=1
167
+ )
168
+
169
+ # Examples section
170
+ gr.Markdown("### πŸ§ͺ Try These Examples")
171
+ gr.Examples(
172
+ examples=examples,
173
+ inputs=[xyz_input, charge_input, spin_input],
174
+ label="Click any example to load it"
175
+ )
176
+
177
+ # Connect button to function
178
+ predict_btn.click(
179
+ predict_molecule,
180
+ inputs=[xyz_input, charge_input, spin_input],
181
+ outputs=[results_output, status_output]
182
+ )
183
+
184
+ # Footer info - matching FAIR Chem UMA style
185
+ with gr.Sidebar(open=True):
186
+ gr.Markdown("## Learn more about OrbMol")
187
+ with gr.Accordion("What is OrbMol?", open=False):
188
+ gr.Markdown("""
189
+ * OrbMol is a neural network potential for molecular property prediction with quantum-level accuracy
190
+ * Built on the Orb-v3 architecture and trained on OMol25 dataset (100M+ DFT calculations)
191
+ * Optimized for biomolecules, metal complexes, and electrolytes
192
+ * Supports configurable charge and spin multiplicity
193
+
194
+ [Read more about OrbMol](https://orbitalmaterials.com/posts/orbmol-extending-orb-to-molecular-systems)
195
+ """)
196
+
197
+ with gr.Accordion("Model Disclaimers", open=False):
198
+ gr.Markdown("""
199
+ * While OrbMol represents significant progress in molecular ML potentials, the model has limitations
200
+ * Always validate results for your specific use case
201
+ * Consider the limitations of the Ο‰B97M-V/def2-TZVPD level of theory used in training
202
+ """)
203
+
204
+ with gr.Accordion("Open source packages", open=False):
205
+ gr.Markdown("""
206
+ * Model code available at [orbital-materials/orb-models](https://github.com/orbital-materials/orb-models)
207
+ * This demo uses ASE, Gradio, and other open source packages
208
+ """)
209
+
210
+ # Load model on startup
211
+ print("πŸš€ Starting OrbMol model loading...")
212
+ load_orbmol_model()
213
+
214
+ if __name__ == "__main__":
215
+ demo.launch(
216
+ server_name="0.0.0.0",
217
+ server_port=7860,
218
+ show_error=True
219
+ )