# importing Liberaries
import streamlit as st
from streamlit_ketcher import st_ketcher
from rdkit import Chem
from rdkit.Chem import Draw, AllChem, rdDetermineBonds, Descriptors
from PIL import Image
import py3Dmol
from stmol import showmol
from stmol import speck_plot
from io import StringIO
import sys
import base64
import subprocess
import time
import datamol as dm
import medchem as mc
import streamlit_shadcn_ui as ui
from molvs import standardize_smiles
from molvs import Standardizer
import pandas as pd
import streamlit_shadcn_ui as ui
try:
# from openbabel import OBMol, OBConversion
import openbabel
except ModuleNotFoundError as e:
subprocess.Popen([f'{sys.executable} -m pip install --global-option=build_ext --global-option="-I/usr/include/openbabel3" --global-option="-L/usr/lib/openbabel" openbabel==2.4.1'], shell=True)
subprocess.Popen([f'{sys.executable} -m pip install --global-option=build_ext --global-option="-I/home/appuser/include/openbabel3" --global-option="-L/home/appuser/lib/openbabel" openbabel==2.4.1'], shell=True)
subprocess.Popen([f'{sys.executable} -m pip install --global-option=build_ext --global-option="-I/home/appuser/usr/include/openbabel3" --global-option="-L/home/appuser/usr/lib/openbabel" openbabel==2.4.1'], shell=True)
# wait for subprocess to install package before running your actual code below
#print('openbabel python not importing')
time.sleep(90)
from openbabel import pybel
#from chemicalconverters import NamesConverter
st.set_page_config(page_title="CHEMSTUDIO24", page_icon="data/favicon.png", layout="centered")
st.logo("data/banner24.png")
tab_titles = ['Home', 'Drawing Arena', 'Rendering and Visualization', 'Representation and Format Conversion', 'Descriptors and Rules',]
tab1, tab2, tab3, tab4, tab5,= st.tabs(tab_titles)
#st.sidebar.link_button("Contact me", "mailto:mohamedelsoudy404@gmail.com")
Titlelogo = Image.open('data/banner24.png')
#st.sidebar.image(Titlelogo)
Titlelogo = Image.open('data/banner24.png')
with tab1:
# banner and header
st.image(Titlelogo)
#st.image(Image.open('data/O=CNc1ccccc1.png'))
#st.link_button("**:gray[@IN SILICO] :violet[CHEMISTRY]**", "https://www.insilicochemistry.io")
#st.link_button(":rainbow[@mohamed elsoudy]", "mailto:mohamedelsoudy404@gmail.com")
# st.markdown('#') #insert space
# show gif
#file_ = open("data/O=CNc1ccccc1.png", "rb")
#contents = file_.read()
#data_url = base64.b64encode(contents).decode("utf-8")
#file_.close()
file_ = open("data/ezgif-3-371bdb31ea-ezgif.com-speed.gif", "rb")
contents = file_.read()
data_url = base64.b64encode(contents).decode("utf-8")
file_.close()
st.markdown(
f'
',
unsafe_allow_html=True,
)
#st.divider()
def support():
link = "https://www.paypal.com/paypalme/insilicochemistry"
file_ = open("data/support.png", "rb")
contents = file_.read()
data_url = base64.b64encode(contents).decode("utf-8")
file_.close()
st.markdown(
f'',
unsafe_allow_html=True, )
def support_button():
url = "https://www.paypal.com/paypalme/insilicochemistry"
st.markdown(f'''
''',
unsafe_allow_html=True)
col1, col2, col3, col4, col5 = st.columns(5)
with col1:
pass
with col2:
pass
with col4:
pass
with col5:
pass
with col3:
pass
#st.link_button("**:white[Support us]**", "https://www.paypal.com/paypalme/insilicochemistry", type="primary")
with tab2:
# KETCHER
st.subheader("Drawing Arena")
molecule = st.text_input("Enter SMILES or Draw your Molecule :art:", "C1=C[SH]=CCO1")
smiles = st_ketcher(molecule, height=800)
stan_smiles = standardize_smiles(smiles)
#converter = NamesConverter(model_name="knowledgator/SMILES2IUPAC-canonical-base")
#st.code(converter.smiles_to_iupac(stan_smiles), "html")
st.code(stan_smiles, "html")
mol = Chem.MolFromSmiles(smiles)
s = Standardizer()
smol = s.standardize(mol)
# RENDERING
def render_2d(mol):
mol = Chem.MolFromSmiles(mol)
s = Standardizer()
smol = s.standardize(mol)
image = Draw.MolToImage(mol, size = (400, 400))
return image
def render_3d(smi):
mol = Chem.MolFromSmiles(smi)
if Hydrogen:
mol = Chem.AddHs(mol)
else:
pass
AllChem.EmbedMolecule(mol)
mblock = Chem.MolToMolBlock(mol)
xyzview = py3Dmol.view( width=400, height=400)
xyzview.addModel(mblock, 'mol')
xyzview.setStyle(stylemd, viewer=(0,0))
xyzview.setBackgroundColor(bcolor)
if box:
xyzview.addBox({'center': {'x': 0,'y': 0,'z': 0},
# 'dimensions': {'w': 1, 'h': 1, 'd': 1}, # scalars
'dimensions': {'w': {'x': 8, 'y': 8, 'z': 0}, #[1, 1, 0], #np.array([1,1,0]),
'h': {'x': 8, 'y': -8, 'z': 0}, # [1, -1, 0], #np.array([1,-1,0]),
'd': {'x': 0, 'y': 0, 'z': 8}, # [0, 0, 1], #np.array([0,0,1]),
},
'color': '#C791FB',
'alpha': 0.5,
})
else:
pass
xyzview.rotate(23, {'x': 1, 'y': 1, 'z': 1})
xyzview.zoomTo()
if spin:
xyzview.spin(True)
else:
xyzview.spin(False)
xyzview.setViewStyle({"style": "outline", "color": "#323232", "width": 0.03}) #CA86FF
#xyzview.addLabel(stan_smiles, {'position': {'x': -6.89, 'y': 0.75, 'z': 0.35},
# 'backgroundColor': '#515151', 'backgroundOpacity': 0.5,'fontSize':18,'fontColor':'#F9F7F7 ',
# 'fontOpacity':1,'borderThickness':0.0,'inFront':'true','showBackground':'true'})
showmol(xyzview,height=400,width=400)
def render_4d(smi):
mol = Chem.MolFromSmiles(smi)
if Hydrogen:
mol = Chem.AddHs(mol)
else:
pass
AllChem.EmbedMolecule(mol)
mblock = Chem.MolToMolBlock(mol)
xyzview = py3Dmol.view( width=400, height=400)
xyzview.addModel(mblock, 'mol')
#xyzview.setStyle({"stick": {'color': '#CA86FF'}, "sphere": {"scale": 0.28, "color":"white"}})
xyzview.setStyle({"stick": {'color': 'gray'}, "sphere": {"scale": 0.28, "color":"white"}})
#xyzview.setViewStyle({"style": "outline", "color": "#CA86FF", "width": 0.04})
xyzview.setBackgroundColor(bcolor)
if box:
xyzview.addBox({'center': {'x': 0,'y': 0,'z': 0},
# 'dimensions': {'w': 1, 'h': 1, 'd': 1}, # scalars
'dimensions': {'w': {'x': 8, 'y': 8, 'z': 0}, #[1, 1, 0], #np.array([1,1,0]),
'h': {'x': 8, 'y': -8, 'z': 0}, # [1, -1, 0], #np.array([1,-1,0]),
'd': {'x': 0, 'y': 0, 'z': 8}, # [0, 0, 1], #np.array([0,0,1]),
},
'color': '#C791FB',
'alpha': 0.5,
})
else:
pass
xyzview.rotate(23, {'x': 1, 'y': 1, 'z': 1})
xyzview.zoomTo()
if spin:
xyzview.spin(True)
else:
xyzview.spin(False)
xyzview.addPropertyLabels('elem',{},{'backgroundOpacity':0, 'fontSize':8, 'fontColor':'gray','alignment':'center','bold':True})
#xyzview.addLabel(stan_smiles, {'position': {'x': -6.89, 'y': 0.75, 'z': 0.35},
# 'backgroundColor': '#515151', 'backgroundOpacity': 0.5,'fontSize':18,'fontColor':'#F9F7F7 ',
# 'fontOpacity':1,'borderThickness':0.0,'inFront':'true','showBackground':'true'})
showmol(xyzview,height=400,width=400)
blk2 = render_2d(smiles)
with tab3:
#st.code(converter.smiles_to_iupac(stan_smiles)[0], "html")
st.code(stan_smiles, "html")
col1, col2= st.columns((4,4))
with col1:
col1.subheader("2D STRUCTURE")
st.image(blk2)
with col2:
col2.subheader("3D STRUCTURE")
st.markdown("Select your Model!")
styles3d = {"Line Model": {"line": {}},
"Cross Model": {"cross":{}},
"Stick Model": {"stick": {}, "sphere": {"scale": 0}},
"Ball and Stick Model": {"stick": {}, "sphere": {"scale": 0.3}},
"CPK Model": {"sphere": {}}
}
list_style = ['Line', 'Cross', 'Stick', 'Ball and Stick', 'CPK']
value = ui.tabs(options=list_style, default_value='Ball and Stick', key="kanaries")
def stylem(value):
if value == list_style[0]:
value2 = styles3d["Line Model"]
elif value == list_style[1]:
value2 = styles3d["Cross Model"]
elif value == list_style[2]:
value2 = styles3d["Stick Model"]
elif value == list_style[3]:
value2 = styles3d["Ball and Stick Model"]
elif value == list_style[4]:
value2 = styles3d["CPK Model"]
return value2
stylemd = stylem(value)
Hydrogen = st.toggle('Add Hydrogens', value=False, key=1)
spin = st.toggle('Animate', value=False, key=2)
box = st.toggle('Show Box', value=False, key=3)
bcolor = st.color_picker('Pick Background Color', '#ffffff', key=4)
render_3d(smiles)
with tab4:
st.subheader("**:gray[Representation and Format] :gray[Conversion]**")
datamol_mol = dm.to_mol(smiles)
#st.markdown(datamol_mol)
def to_smarts(datamol_mol):
smarts = dm.smiles_as_smarts(datamol_mol)
st.code(smarts, "html")
def to__inchi(datamol_mol):
inchi = dm.to_inchi(datamol_mol)
st.code(inchi, "html")
def to__inchikey(datamol_mol):
inchikey = dm.to_inchikey(datamol_mol)
st.code(inchikey, "html")
def to_xyz(smiles, unsafe_allow_html=True):
mol = Chem.MolFromSmiles(smiles)
mol_h = Chem.AddHs(mol)
AllChem.EmbedMolecule(mol_h)
xyz = Chem.MolToXYZBlock(mol_h)
mol2 = Chem.MolFromXYZBlock(xyz)
rdDetermineBonds.DetermineBonds(mol2)
xyz = Chem.MolToXYZBlock(mol2)
st.code(xyz,"html")
st.download_button(label="Download .xyz File", data=xyz,
file_name=f'{stan_smiles}' + "." + "xyz", mime='text/csv', )
def to_rdkit3d(smiles):
mol = Chem.MolFromSmiles(smiles)
mol_h = Chem.AddHs(mol)
AllChem.EmbedMolecule(mol_h)
xyz = Chem.MolToXYZBlock(mol_h)
mol2 = Chem.MolFromXYZBlock(xyz)
rdDetermineBonds.DetermineBonds(mol2)
xyz = Chem.MolToXYZBlock(mol2)
input_geom_str = xyz
mol2 = pybel.readstring("xyz", input_geom_str)
# mol.make3D()
output_geom_str = mol2.write("mol")
st.code(output_geom_str,"html")
st.download_button(label="Download .mol File", data=output_geom_str,
file_name=f'{stan_smiles}' + "." + "mol", mime='text/csv', )
def to_sdf(smiles):
mol = Chem.MolFromSmiles(smiles)
mol_h = Chem.AddHs(mol)
AllChem.EmbedMolecule(mol_h)
xyz = Chem.MolToXYZBlock(mol_h)
mol2 = Chem.MolFromXYZBlock(xyz)
rdDetermineBonds.DetermineBonds(mol2)
xyz = Chem.MolToXYZBlock(mol2)
input_geom_str = xyz
mol2 = pybel.readstring("xyz", input_geom_str)
# mol.make3D()
output_geom_str = mol2.write("sdf")
st.code(output_geom_str,"html")
st.download_button(label="Download .sdf File", data=output_geom_str,
file_name=f'{stan_smiles}' + "." + "sdf", mime='text/csv', )
def to_cif(smiles):
mol = Chem.MolFromSmiles(smiles)
mol_h = Chem.AddHs(mol)
AllChem.EmbedMolecule(mol_h)
xyz = Chem.MolToXYZBlock(mol_h)
mol2 = Chem.MolFromXYZBlock(xyz)
rdDetermineBonds.DetermineBonds(mol2)
xyz = Chem.MolToXYZBlock(mol2)
input_geom_str = xyz
mol2 = pybel.readstring("xyz", input_geom_str)
# mol.make3D()
output_geom_str = mol2.write("cif")
st.code(output_geom_str,"html")
st.download_button(label="Download .cif File", data=output_geom_str,
file_name=f'{stan_smiles}' + "." + "cif", mime='text/csv', )
def to_pdb(smiles):
mol = Chem.MolFromSmiles(smiles)
mol_h = Chem.AddHs(mol)
AllChem.EmbedMolecule(mol_h)
xyz = Chem.MolToXYZBlock(mol_h)
mol2 = Chem.MolFromXYZBlock(xyz)
rdDetermineBonds.DetermineBonds(mol2)
xyz = Chem.MolToXYZBlock(mol2)
input_geom_str = xyz
mol2 = pybel.readstring("xyz", input_geom_str)
# mol.make3D()
output_geom_str = mol2.write("pdb")
st.code(output_geom_str,"html")
st.download_button(label="Download .pdb File", data=output_geom_str,
file_name=f'{stan_smiles}' + "." + "pdb", mime='text/csv', )
SMILES_OUT = st.selectbox("Select Output!",["SMARTS", "InChI", "InChIKey", "mol", "sdf", "xyz", "cif", "pdb"])
if SMILES_OUT == "SMARTS":
to_smarts(datamol_mol)
elif SMILES_OUT == "InChI":
to__inchi(datamol_mol)
elif SMILES_OUT == "InChIKey":
to__inchikey(datamol_mol)
elif SMILES_OUT == "xyz":
to_xyz(smiles, unsafe_allow_html=True)
elif SMILES_OUT == "mol":
to_rdkit3d(smiles)
elif SMILES_OUT == "sdf":
to_sdf(smiles)
elif SMILES_OUT == "cif":
to_cif(smiles)
elif SMILES_OUT == "pdb":
to_pdb(smiles)
with tab5:
my_dict = {'SMILES': stan_smiles,
'Molecular Weight': Descriptors.MolWt(smol),
'Number of H Acceptors': Descriptors.NumHAcceptors(smol),
'Number of H Donors': Descriptors.NumHDonors(smol),
'Octanol/Water Partition Coefficient LogP': Descriptors.MolLogP(smol),
"Topological Polar Surface Area (TPSA)": Descriptors.TPSA(smol),
"Lipinski's Rule of 5": mc.rules.basic_rules.rule_of_five(datamol_mol),
"Pfizer Rule 3/75": mc.rules.basic_rules.rule_of_pfizer_3_75(datamol_mol)
}
new = pd.DataFrame.from_dict([my_dict],)
new = new.rename(index={0: 'Descriptors and Rules'})
NEWT = new.T
st.dataframe(NEWT)
NEWT = NEWT.to_csv(index=True).encode('utf-8')
st.download_button(
"Download data!",
NEWT,
f"{stan_smiles}"+" Descriptors_Rules"+".csv",
"text/csv",
key='download-csv'
)