Spaces:
Paused
Paused
Download src/conformers.py from VSRAJHAVEL/BioGraph-AI: direct link, hf CLI and curl.
- Browser
- Download file 4.21 kB
-
https://huggingface.co/spaces/VSRAJHAVEL/BioGraph-AI/resolve/main/src/conformers.py
- Command line
-
hf download hf://spaces/VSRAJHAVEL/BioGraph-AI/src/conformers.py
-
curl -L -o conformers.py https://huggingface.co/spaces/VSRAJHAVEL/BioGraph-AI/resolve/main/src/conformers.py
4.21 kB
| """ | |
| 3D Conformer Generation and Interactive Molecular Modeling. | |
| Generates energetic 3D molecular conformations using ETKDG and MMFF94 force field, | |
| and constructs py3Dmol visualizer HTML blocks for Streamlit components. | |
| """ | |
| from typing import Tuple, Optional | |
| from rdkit import Chem | |
| from rdkit.Chem import AllChem | |
| import py3Dmol | |
| def generate_3d_conformer(smiles_or_mol: any, seed: int = 42) -> Tuple[Optional[Chem.Mol], Optional[str], Optional[float], str]: | |
| """ | |
| Generate an energy-minimized 3D conformer for a molecule. | |
| Args: | |
| smiles_or_mol: SMILES string or RDKit Mol object. | |
| seed: Random seed for deterministic coordinate embedding. | |
| Returns: | |
| Tuple of (mol_3d, mol_block_str, energy_kcal_per_mol, status_message) | |
| """ | |
| if isinstance(smiles_or_mol, str): | |
| mol = Chem.MolFromSmiles(smiles_or_mol) | |
| else: | |
| mol = Chem.Mol(smiles_or_mol) | |
| if mol is None: | |
| return None, None, None, "Invalid chemical structure" | |
| mol_h = Chem.AddHs(mol) | |
| # Use ETKDG embedding | |
| params = AllChem.ETKDGv3() if hasattr(AllChem, 'ETKDGv3') else AllChem.ETKDG() | |
| params.randomSeed = seed | |
| embed_code = AllChem.EmbedMolecule(mol_h, params) | |
| if embed_code != 0: | |
| # Fallback with relaxed distance geometry | |
| embed_code = AllChem.EmbedMolecule(mol_h, randomSeed=seed, useRandomCoords=True) | |
| if embed_code != 0: | |
| return None, None, None, "Failed to embed 3D coordinates" | |
| # MMFF94 Force Field Optimization | |
| energy = None | |
| status = "MMFF94 optimized" | |
| if AllChem.MMFFHasAllMoleculeParams(mol_h): | |
| mmff_props = AllChem.MMFFGetMoleculeProperties(mol_h) | |
| ff = AllChem.MMFFGetMoleculeForceField(mol_h, mmff_props) | |
| if ff: | |
| ff.Initialize() | |
| ff.Minimize(maxIts=500) | |
| energy = float(ff.CalcEnergy()) | |
| else: | |
| # Fallback to Universal Force Field (UFF) | |
| if AllChem.UFFHasAllMoleculeParams(mol_h): | |
| ff = AllChem.UFFGetMoleculeForceField(mol_h) | |
| if ff: | |
| ff.Initialize() | |
| ff.Minimize(maxIts=500) | |
| energy = float(ff.CalcEnergy()) | |
| status = "UFF optimized (MMFF params unavailable for this element)" | |
| mol_block = Chem.MolToMolBlock(mol_h) | |
| return mol_h, mol_block, energy, status | |
| def render_3dmol_html( | |
| mol_block: str, | |
| style: str = "stick", | |
| surface_type: str = "none", | |
| spin: bool = False, | |
| width: int = 500, | |
| height: int = 400 | |
| ) -> str: | |
| """ | |
| Generate self-contained HTML for interactive 3D molecular visualization using py3Dmol. | |
| Args: | |
| mol_block: MDL MolBlock representation of the 3D conformer. | |
| style: Visual representation ('stick', 'ball_and_stick', 'sphere', 'wireframe'). | |
| surface_type: Molecular surface representation ('none', 'vdw', 'sas', 'ses'). | |
| spin: Whether to enable auto-rotation. | |
| width: Viewer width in pixels. | |
| height: Viewer height in pixels. | |
| Returns: | |
| HTML string suitable for st.components.v1.html. | |
| """ | |
| view = py3Dmol.view(width=width, height=height) | |
| view.addModel(mol_block, "mol") | |
| if style == "stick": | |
| view.setStyle({'stick': {'radius': 0.18, 'colorscheme': 'cyanCarbon'}}) | |
| elif style == "ball_and_stick": | |
| view.setStyle({ | |
| 'stick': {'radius': 0.14, 'colorscheme': 'cyanCarbon'}, | |
| 'sphere': {'scale': 0.28, 'colorscheme': 'cyanCarbon'} | |
| }) | |
| elif style == "sphere": | |
| view.setStyle({'sphere': {'scale': 0.85, 'colorscheme': 'cyanCarbon'}}) | |
| elif style == "wireframe": | |
| view.setStyle({'line': {'linewidth': 2.0, 'colorscheme': 'cyanCarbon'}}) | |
| else: | |
| view.setStyle({'stick': {}}) | |
| # Optional molecular surface | |
| surf_map = { | |
| 'vdw': py3Dmol.VDW, | |
| 'sas': py3Dmol.SAS, | |
| 'ses': py3Dmol.SES | |
| } | |
| if surface_type.lower() in surf_map: | |
| view.addSurface(surf_map[surface_type.lower()], {'opacity': 0.65, 'color': 'lightblue'}) | |
| if spin: | |
| view.spin(True) | |
| view.zoomTo() | |
| view.setBackgroundColor('#0f172a') # Dark slate background for premium biotech feel | |
| return view._make_html() | |