Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import torch | |
| import numpy as np | |
| from ase import Atoms | |
| from ase.io import read, write | |
| import tempfile | |
| import os | |
| from orb_models.forcefield import pretrained | |
| from orb_models.forcefield.calculator import ORBCalculator | |
| # Global variable for the model | |
| model_calc = None | |
| def load_orbmol_model(): | |
| """Load OrbMol model once""" | |
| global model_calc | |
| if model_calc is None: | |
| try: | |
| print("Loading OrbMol model...") | |
| orbff = pretrained.orb_v3_conservative_inf_omat( | |
| device="cpu", | |
| precision="float32-high" | |
| ) | |
| model_calc = ORBCalculator(orbff, device="cpu") | |
| print("β OrbMol model loaded successfully") | |
| except Exception as e: | |
| print(f"β Error loading model: {e}") | |
| model_calc = None | |
| return model_calc | |
| def predict_molecule(xyz_content, charge=0, spin_multiplicity=1): | |
| """ | |
| Main function: XYZ β OrbMol β Results | |
| """ | |
| try: | |
| # Load model | |
| calc = load_orbmol_model() | |
| if calc is None: | |
| return "β Error: Could not load OrbMol model", "" | |
| if not xyz_content.strip(): | |
| return "β Error: Please enter XYZ coordinates", "" | |
| # Create temporary file with XYZ | |
| with tempfile.NamedTemporaryFile(mode='w', suffix='.xyz', delete=False) as f: | |
| f.write(xyz_content) | |
| xyz_file = f.name | |
| # Read molecular structure | |
| atoms = read(xyz_file) | |
| # Configure charge and spin (IMPORTANT for OrbMol!) | |
| atoms.info = { | |
| "charge": int(charge), | |
| "spin": int(spin_multiplicity) | |
| } | |
| # Assign OrbMol calculator | |
| atoms.calc = calc | |
| # Make the prediction! | |
| energy = atoms.get_potential_energy() # In eV | |
| forces = atoms.get_forces() # In eV/Γ | |
| # Format results nicely | |
| result = f""" | |
| π **Total Energy**: {energy:.6f} eV | |
| β‘ **Atomic Forces**: | |
| """ | |
| for i, force in enumerate(forces): | |
| result += f"Atom {i+1}: [{force[0]:.4f}, {force[1]:.4f}, {force[2]:.4f}] eV/Γ \n" | |
| # Additional statistics | |
| max_force = np.max(np.linalg.norm(forces, axis=1)) | |
| result += f"\nπ **Max Force**: {max_force:.4f} eV/Γ " | |
| # Clean up temporary file | |
| os.unlink(xyz_file) | |
| return result, "β Calculation completed with OrbMol" | |
| except Exception as e: | |
| return f"β Error during calculation: {str(e)}", "Error" | |
| # Predefined examples | |
| examples = [ | |
| ["""2 | |
| Hydrogen molecule | |
| H 0.0 0.0 0.0 | |
| H 0.0 0.0 0.74""", 0, 1], | |
| ["""3 | |
| Water molecule | |
| O 0.0000 0.0000 0.0000 | |
| H 0.7571 0.0000 0.5864 | |
| H -0.7571 0.0000 0.5864""", 0, 1], | |
| ["""4 | |
| Methane | |
| C 0.0000 0.0000 0.0000 | |
| H 1.0890 0.0000 0.0000 | |
| H -0.3630 1.0267 0.0000 | |
| H -0.3630 -0.5133 0.8887 | |
| H -0.3630 -0.5133 -0.8887""", 0, 1] | |
| ] | |
| # Gradio interface - using FAIR Chem UMA style | |
| with gr.Blocks(theme=gr.themes.Ocean(), title="OrbMol Demo") as demo: | |
| with gr.Row(): | |
| with gr.Column(scale=2): | |
| with gr.Column(variant="panel"): | |
| gr.Markdown("# OrbMol Demo - Quantum-Accurate Molecular Predictions") | |
| gr.Markdown(""" | |
| **OrbMol** is a neural network potential trained on the **OMol25** dataset (100M+ high-accuracy DFT calculations). | |
| Predicts **energies** and **forces** with quantum accuracy, optimized for: | |
| * 𧬠Biomolecules | |
| * βοΈ Metal complexes | |
| * π Electrolytes | |
| """) | |
| gr.Markdown("## Simulation inputs") | |
| with gr.Column(variant="panel"): | |
| gr.Markdown("### Input molecular structure") | |
| xyz_input = gr.Textbox( | |
| label="XYZ Coordinates", | |
| placeholder="""3 | |
| Water molecule | |
| O 0.0000 0.0000 0.0000 | |
| H 0.7571 0.0000 0.5864 | |
| H -0.7571 0.0000 0.5864""", | |
| lines=12, | |
| info="Paste XYZ coordinates of your molecule here" | |
| ) | |
| gr.Markdown("OMol-specific settings for total charge and spin multiplicity") | |
| with gr.Row(): | |
| charge_input = gr.Slider( | |
| value=0, label="Total Charge", minimum=-10, maximum=10, step=1 | |
| ) | |
| spin_input = gr.Slider( | |
| value=1, maximum=11, minimum=1, step=1, label="Spin Multiplicity" | |
| ) | |
| predict_btn = gr.Button("Run OrbMol Prediction", variant="primary", size="lg") | |
| with gr.Column(variant="panel", elem_id="results", min_width=500): | |
| gr.Markdown("## OrbMol Prediction Results") | |
| results_output = gr.Textbox( | |
| label="Energy & Forces", | |
| lines=15, | |
| interactive=False, | |
| info="OrbMol energy and force predictions" | |
| ) | |
| status_output = gr.Textbox( | |
| label="Status", | |
| interactive=False, | |
| max_lines=1 | |
| ) | |
| # Examples section | |
| gr.Markdown("### π§ͺ Try These Examples") | |
| gr.Examples( | |
| examples=examples, | |
| inputs=[xyz_input, charge_input, spin_input], | |
| label="Click any example to load it" | |
| ) | |
| # Connect button to function | |
| predict_btn.click( | |
| predict_molecule, | |
| inputs=[xyz_input, charge_input, spin_input], | |
| outputs=[results_output, status_output] | |
| ) | |
| # Footer info - matching FAIR Chem UMA style | |
| with gr.Sidebar(open=True): | |
| gr.Markdown("## Learn more about OrbMol") | |
| with gr.Accordion("What is OrbMol?", open=False): | |
| gr.Markdown(""" | |
| * OrbMol is a neural network potential for molecular property prediction with quantum-level accuracy | |
| * Built on the Orb-v3 architecture and trained on OMol25 dataset (100M+ DFT calculations) | |
| * Optimized for biomolecules, metal complexes, and electrolytes | |
| * Supports configurable charge and spin multiplicity | |
| [Read more about OrbMol](https://orbitalmaterials.com/posts/orbmol-extending-orb-to-molecular-systems) | |
| """) | |
| with gr.Accordion("Model Disclaimers", open=False): | |
| gr.Markdown(""" | |
| * While OrbMol represents significant progress in molecular ML potentials, the model has limitations | |
| * Always validate results for your specific use case | |
| * Consider the limitations of the ΟB97M-V/def2-TZVPD level of theory used in training | |
| """) | |
| with gr.Accordion("Open source packages", open=False): | |
| gr.Markdown(""" | |
| * Model code available at [orbital-materials/orb-models](https://github.com/orbital-materials/orb-models) | |
| * This demo uses ASE, Gradio, and other open source packages | |
| """) | |
| # Load model on startup | |
| print("π Starting OrbMol model loading...") | |
| load_orbmol_model() | |
| if __name__ == "__main__": | |
| demo.launch( | |
| server_name="0.0.0.0", | |
| server_port=7860, | |
| show_error=True | |
| ) |