CHEMVERTINA / app.py
S0udy's picture
Update app.py
57b84e6 verified
import streamlit as st
from streamlit_ketcher import st_ketcher
from rdkit import Chem
from rdkit.Chem import Draw, AllChem, rdDetermineBonds, Descriptors
import py3Dmol
from stmol import showmol
from io import StringIO
import sys
import subprocess
import time
import streamlit_shadcn_ui as ui
import streamlit_shadcn_ui as ui
from PIL import Image
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
st.set_page_config(page_title="CHEMVERTINA", page_icon="data/favicon.png", layout="centered")
st.write("### **:rainbow[CHEMVERTINA] :gray[| Your Molecule Playground]**")
Titlelogo = Image.open('data/logo.png')
st.image(Titlelogo)
st.markdown((":gray[Visualize and Convert your] :rainbow[Molecule]"))
st.divider()
supported_input_formats = ['xyz', 'cif', 'pdb', 'mol', 'mol2', 'sdf', 'tmol', 'poscar', 'cub', 'cube', 'mcif', 'mmcif', 'pwscf', 'smi']
supported_output_formats = ['cif', 'tmol', 'xyz', 'sdf', 'pdb', 'smiles', 'mcif', 'mmcif', 'mdl', 'mol', 'mol2', 'smi',]
data = '''12
C 1.525098 0.401299 -0.169919
C 1.267282 -0.890923 -0.090842
S -0.375869 -1.429467 -0.350672
C -1.364069 -0.186583 -0.232712
C -0.787332 1.146673 0.059053
O 0.519018 1.327928 -0.452149
H 2.534310 0.743140 -0.012656
H 2.085372 -1.592058 0.136539
H -0.704143 -2.346960 0.640753
H -2.462024 -0.305561 -0.365090
H -0.753918 1.233523 1.179450
H -1.483725 1.898990 -0.341753
'''
# st.components.v1.iframe("https://pubchem.ncbi.nlm.nih.gov/periodic-table/#view=table&embed=true", width=800, height=800, scrolling=True)
col1, col2 = st.columns(2)
col1.write('## Input Molecule')
input_format = col1.selectbox('Firstly, select the input file format',
supported_input_formats, )
input_text_area = col1.empty()
uploaded_file = col1.file_uploader("or Choose a file from your local data")
if uploaded_file is not None:
# To read file as bytes:
bytes_data = uploaded_file.getvalue()
#uploaded_file_name = uploaded_file.name.split(".")
#input_up_format = uploaded_file_name[-1]
# To convert to a string based IO:
stringio = StringIO(uploaded_file.getvalue().decode("utf-8"))
# To read file as string:
string_data = stringio.read()
placeholder_xyz_str = string_data
input_geom_str = input_text_area.text_area(label='Enter the contents of the source file here', value = placeholder_xyz_str, placeholder = 'Put your text here', height=400)
elif uploaded_file is None:
input_geom_str = input_text_area.text_area(label='Secondly, paste the file contents here', value = data, placeholder = 'Paste the contents of your file here', height=400, key = 'input_text_area')
# # Get rid of empty lines
# input_geom_str = os.linesep.join([s for s in input_geom_str.splitlines() if s])
mol = pybel.readstring(input_format, input_geom_str)
# mol.make3D()
## OUTPUT ##
col2.write('## Output')
output_format = col2.selectbox('Select the output file format',
supported_output_formats)
output_geom_str = mol.write(output_format)
col2.text_area(label='Converted file structure', value=output_geom_str, height=400)
col2.download_button(
label="Download the output",
data=output_geom_str,
file_name='your_new_output.'+output_format,
mime='text/csv',)
st.divider()
st.subheader("Visualization Scene")
col3, col4 = st.columns(2)
def vis_your_molecule():
newviewer = py3Dmol.view(width=400, height=400)
structure_for_visualization = ''
try:
mol = pybel.readstring(input_format, input_geom_str)
# mol.make3D()
structure_for_visualization = mol.write('xyz')
except Exception as e:
print('There was a problem with the conversion', e)
newviewer.addModel(structure_for_visualization, 'xyz')
newviewer.setBackgroundColor(bcolor2)
newviewer.setStyle(stylemd2)
newviewer.setViewStyle({"style": "outline", "color": "#323232", "width": 0.03})
if spin2:
newviewer.spin(True)
else:
newviewer.spin(False)
if box2:
newviewer.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
showmol(newviewer,height=400,width=400)
with col3:
st.markdown("Select your Model!")
styles3d2 = {"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_style2 = ['Line', 'Cross', 'Stick', 'Ball and Stick', 'CPK']
value2 = ui.tabs(options=list_style2, default_value='Ball and Stick', key="flowers")
spin2 = st.toggle('Animate', value=False, key=5)
box2 = st.toggle('Show Box', value=False, key=6)
bcolor2 = st.color_picker('Pick Background Color', '#ffffff', key=7)
def stylem2(value2):
if value2 == list_style2[0]:
value4 = styles3d2["Line Model"]
elif value2 == list_style2[1]:
value4 = styles3d2["Cross Model"]
elif value2 == list_style2[2]:
value4 = styles3d2["Stick Model"]
elif value2 == list_style2[3]:
value4 = styles3d2["Ball and Stick Model"]
elif value2 == list_style2[4]:
value4 = styles3d2["CPK Model"]
return value4
stylemd2 = stylem2(value2)
with col4:
vis_your_molecule()