Spaces:
Runtime error
Runtime error
import streamlit as st | |
import ipywidgets | |
import py3Dmol | |
from rdkit import Chem | |
from rdkit.Chem import Draw | |
from PIL import Image | |
from rdkit import Chem | |
from rdkit.Chem import AllChem | |
from ipywidgets import interact,fixed,IntSlider | |
import streamlit as st | |
import streamlit.components.v1 as components | |
import py3Dmol | |
from rdkit import Chem | |
from rdkit.Chem import Draw | |
from rdkit.Chem import AllChem | |
def smi2conf(smiles): | |
'''Convert SMILES to rdkit.Mol with 3D coordinates''' | |
mol = Chem.MolFromSmiles(smiles) | |
if mol is not None: | |
mol = Chem.AddHs(mol) | |
AllChem.EmbedMolecule(mol) | |
AllChem.MMFFOptimizeMolecule(mol, maxIters=200) | |
return mol | |
else: | |
return None | |
def MolTo3DView(mol, size=(300, 300), style="stick", surface=False, opacity=0.5): | |
"""Draw molecule in 3D | |
Args: | |
---- | |
mol: rdMol, molecule to show | |
size: tuple(int, int), canvas size | |
style: str, type of drawing molecule | |
style can be 'line', 'stick', 'sphere', 'carton' | |
surface, bool, display SAS | |
opacity, float, opacity of surface, range 0.0-1.0 | |
Return: | |
---- | |
viewer: py3Dmol.view, a class for constructing embedded 3Dmol.js views in ipython notebooks. | |
""" | |
assert style in ('line', 'stick', 'sphere', 'carton') | |
mblock = Chem.MolToMolBlock(mol) | |
viewer = py3Dmol.view(width=size[0], height=size[1]) | |
viewer.addModel(mblock, 'mol') | |
viewer.setStyle({style:{}}) | |
if surface: | |
viewer.addSurface(py3Dmol.SAS, {'opacity': opacity}) | |
viewer.zoomTo() | |
return viewer | |
def MakeMolecule(name, ingredients): | |
st.write(name) | |
m = Chem.MolFromSmiles(ingredients) | |
im=Draw.MolToImage(m) | |
st.image(im) | |
def conf_viewer(idx): | |
mol = confs[idx] | |
return MolTo3DView(mol).show() | |
def style_selector(idx, s): | |
conf = confs[idx] | |
return MolTo3DView(conf, style=s).show() | |
def smi2viewer(smi='CC=O'): | |
try: | |
conf = smi2conf(smi) | |
return MolTo3DView(conf).show() | |
except: | |
return None | |
smi = 'COc3nc(OCc2ccc(C#N)c(c1ccc(C(=O)O)cc1)c2P(=O)(O)O)ccc3C[NH2+]CC(I)NC(=O)C(F)(Cl)Br' | |
conf = smi2conf(smi) | |
viewer = MolTo3DView(conf, size=(600, 300), style='sphere') | |
viewer.show() | |
compound_smiles = 'c1cc(C(=O)O)c(OC(=O)C)cc1' | |
m = Chem.MolFromSmiles(compound_smiles) | |
im=Draw.MolToImage(m) | |
st.image(im) | |
MakeMolecule("Ethanol", "CCO") | |
MakeMolecule("Acetic acid", "CC(=O)O") | |
MakeMolecule("Cyclohexane", "C1CCCCC1") | |
MakeMolecule("Pyridine", "c1cnccc1") | |
viewer = MolTo3DView(conf, size=(600, 300), style='sphere') | |
viewer.show() | |
smis = [ 'COc3nc(OCc2ccc(C#N)c(c1ccc(C(=O)O)cc1)c2P(=O)(O)O)ccc3C[NH2+]CC(I)NC(=O)C(F)(Cl)Br', | |
'CC(NCCNCC1=CC=C(OCC2=C(C)C(C3=CC=CC=C3)=CC=C2)N=C1OC)=O', | |
'Cc1c(COc2cc(OCc3cccc(c3)C#N)c(CN3C[C@H](O)C[C@H]3C(O)=O)cc2Cl)cccc1-c1ccc2OCCOc2c1', | |
'CCCCC(=O)NCCCCC(=O)NCCCCCC(=O)[O-]', | |
"CC(NCCNCC1=CC=C(OCC2=C(C)C(C3=CC=CC=C3)=CC=C2)N=C1OC)=O"] | |
confs = [smi2conf(s) for s in smis] | |
st.title('SMILES + RDKit + Py3DMOL :smiley:') | |
def show(smi, style='stick'): | |
mol = Chem.MolFromSmiles(smi) | |
mol = Chem.AddHs(mol) | |
AllChem.EmbedMolecule(mol) | |
AllChem.MMFFOptimizeMolecule(mol, maxIters=200) | |
mblock = Chem.MolToMolBlock(mol) | |
view = py3Dmol.view(width=400, height=400) | |
view.addModel(mblock, 'mol') | |
view.setStyle({style:{}}) | |
view.zoomTo() | |
view.show() | |
view.render() | |
t =view.js() | |
f = open('viz.html', 'w') | |
f.write(t.startjs) | |
f.write(t.endjs) | |
f.close() | |
compound_smiles=st.text_input('SMILES please','CC') | |
m = Chem.MolFromSmiles(compound_smiles) | |
Draw.MolToFile(m,'mol.png') | |
show(compound_smiles) | |
HtmlFile = open("viz.html", 'r', encoding='utf-8') | |
source_code = HtmlFile.read() | |
c1,c2=st.beta_columns(2) | |
with c1: | |
st.write('Molecule :coffee:') | |
st.image('mol.png') | |
with c2: | |
components.html(source_code, height = 400,width=400) | |
################ Sidebar #################### | |
with st.sidebar.beta_expander('Rule One (Atoms and Bonds)'): | |
st.markdown(''' | |
## Atoms | |
|If |then | | |
|----|----| | |
| Non-aromatic atoms |Uper case letters | | |
| Aromatic atoms |lower case letters | | |
|Atomic symbols has more than one letter | The second is lower case | | |
## Bonds | |
| Bond type| Bond symbol | | |
|---|---| | |
|Simple | - | | |
|Double|=| | |
|Triple|#| | |
|Aromatic|*| | |
| Disconnected structures|. | | |
### Example: | |
CC 👉 There is a non-aromatic carbon attached to another non-aromatic carbon by a single bond. | |
🛑 A bond between two lower case atom symbols is *aromatic*. | |
''') | |
with st.sidebar.beta_expander('Rule Two (Simple Chains)'): | |
st.markdown(''' | |
## Simple chains | |
* Structures are hydrogen suppresed (Molecules represented without hydrogens) | |
* If enough bonds are not identified by the user, the system will assume that connections | |
are satisfied by hidrogens. | |
* The user can explicitly identify hydrogen bonds, but if so the interpreter will assume that all of them are fully identified. | |
Note: | |
*Because SMILES allows entry of all elements in the periodic table, | |
and also utilizes hydrogen suppression, the user should be aware of chemicals with two letters | |
that could be misinterpreted by the computer. For example, 'Sc' could be interpreted as a **sulfur** | |
atom connected to an aromatic **carbon** by a single bond, or it could be the symbol for **scandium**. | |
The SMILES interpreter gives priority to the interpretation of a single bond connecting a sulfur atom and an aromatic carbon. | |
To identify scandium the user should enter [Sc]*. | |
''') | |
with st.sidebar.beta_expander('Rule Three (Branches)'): | |
st.markdown(''' | |
## Branches | |
* A branch from a chain is specified by placing the SMILES symbol(s) for the branch between parenthesis. | |
* The string in parentheses is placed directly after the symbol for the atom to which it is connected. | |
* If it is connected by a double or triple bond, the bond symbol immediately follows the left parenthesis. | |
''') | |
with st.sidebar.beta_expander('Rule Four (Rings)'): | |
st.markdown(''' | |
## Rings | |
* SMILES allows a user to identify ring structures by using numbers to identify the opening and closing ring atom. | |
For example, in C1CCCCC1, the first carbon has a number '1' which connects by a single bond with the last carbon which also has a number '1'. | |
The resulting structure is cyclohexane. Chemicals that have multiple rings may be identified by using different numbers for each ring. | |
* If a double, single, or aromatic bond is used for the ring closure, the bond symbol is placed before the ring closure number. | |
''') | |
with st.sidebar.beta_expander('Rule Five (Charged atoms)'): | |
st.markdown(''' | |
## Charged atoms | |
Charges on an atom can be used to override the knowledge regarding valence that is built into SMILES software. | |
The format for identifying a charged atom consists of the atom followed by brackets which enclose the charge on the atom. | |
The number of charges may be explicitly stated ({-1}) or not ({-}). | |
''') | |
st.sidebar.markdown('Original Author: José Manuel Nápoles ([@napoles3d](https://twitter.com/napoles3D)). Find original app in https://share.streamlit.io/napoles-uach/st_smiles/main/smiles.py') | |
st.sidebar.write('Info about SMILES: https://archive.epa.gov/med/med_archive_03/web/html/smiles.html') | |