Spaces:
Running
Running
Upload 13 files
Browse files- .gitattributes +1 -0
- .streamlit/config.toml +3 -0
- app.py +10 -0
- chemstudio24.py +380 -0
- data/baa.gif +3 -0
- data/banner.png +0 -0
- data/banner24.png +0 -0
- data/favicon.png +0 -0
- data/speck.png +0 -0
- data/speck24.png +0 -0
- environment_backup.yml +10 -0
- packages.txt +2 -0
- requirements.txt +20 -0
- your_molecule.py +180 -0
.gitattributes
CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
36 |
+
data/baa.gif filter=lfs diff=lfs merge=lfs -text
|
.streamlit/config.toml
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
[theme]
|
2 |
+
base="light"
|
3 |
+
primaryColor="#b99de4"
|
app.py
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# importing Liberaries
|
2 |
+
|
3 |
+
import streamlit as st
|
4 |
+
|
5 |
+
|
6 |
+
chemstudio24_page = st.Page("chemstudio24.py", title="CHEMSTUDIO24", default=True)
|
7 |
+
your_molecule_playground_page = st.Page('your_molecule.py', title = "Your Molecule Playground", icon=":material/splitscreen_left:")
|
8 |
+
multi_pages = st.navigation([chemstudio24_page, your_molecule_playground_page])
|
9 |
+
multi_pages.run()
|
10 |
+
|
chemstudio24.py
ADDED
@@ -0,0 +1,380 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# importing Liberaries
|
2 |
+
|
3 |
+
import streamlit as st
|
4 |
+
from streamlit_ketcher import st_ketcher
|
5 |
+
from rdkit import Chem
|
6 |
+
from rdkit.Chem import Draw, AllChem, rdDetermineBonds, Descriptors
|
7 |
+
|
8 |
+
from PIL import Image
|
9 |
+
import py3Dmol
|
10 |
+
from stmol import showmol
|
11 |
+
from stmol import speck_plot
|
12 |
+
from io import StringIO
|
13 |
+
import sys
|
14 |
+
import base64
|
15 |
+
import subprocess
|
16 |
+
import time
|
17 |
+
import datamol as dm
|
18 |
+
import medchem as mc
|
19 |
+
import streamlit_shadcn_ui as ui
|
20 |
+
from molvs import standardize_smiles
|
21 |
+
from molvs import Standardizer
|
22 |
+
import pandas as pd
|
23 |
+
import streamlit_shadcn_ui as ui
|
24 |
+
|
25 |
+
|
26 |
+
try:
|
27 |
+
# from openbabel import OBMol, OBConversion
|
28 |
+
import openbabel
|
29 |
+
except ModuleNotFoundError as e:
|
30 |
+
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)
|
31 |
+
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)
|
32 |
+
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)
|
33 |
+
# wait for subprocess to install package before running your actual code below
|
34 |
+
#print('openbabel python not importing')
|
35 |
+
time.sleep(90)
|
36 |
+
|
37 |
+
from openbabel import pybel
|
38 |
+
|
39 |
+
#from chemicalconverters import NamesConverter
|
40 |
+
|
41 |
+
|
42 |
+
st.set_page_config(page_title="CHEMSTUDIO24", page_icon="data/favicon.png", layout="centered")
|
43 |
+
st.logo("data/banner24.png")
|
44 |
+
|
45 |
+
|
46 |
+
|
47 |
+
tab_titles = ['Home', 'Drawing Arena', 'Rendering and Visualization', 'Representation and Format Conversion', 'Descriptors and Rules',]
|
48 |
+
tab1, tab2, tab3, tab4, tab5,= st.tabs(tab_titles)
|
49 |
+
|
50 |
+
|
51 |
+
|
52 |
+
#st.sidebar.link_button("Contact me", "mailto:mohamedelsoudy404@gmail.com")
|
53 |
+
Titlelogo = Image.open('data/banner24.png')
|
54 |
+
#st.sidebar.image(Titlelogo)
|
55 |
+
Titlelogo = Image.open('data/banner24.png')
|
56 |
+
|
57 |
+
|
58 |
+
with tab1:
|
59 |
+
|
60 |
+
# banner and header
|
61 |
+
st.image(Titlelogo)
|
62 |
+
|
63 |
+
st.link_button("**:gray[@IN SILICO] :violet[CHEMISTRY]**", "https://www.insilicochemistry.io")
|
64 |
+
st.link_button(":rainbow[@mohamed elsoudy]", "mailto:mohamedelsoudy404@gmail.com")
|
65 |
+
# st.markdown('#') #insert space
|
66 |
+
|
67 |
+
# show gif
|
68 |
+
file_ = open("data/baa.gif", "rb")
|
69 |
+
contents = file_.read()
|
70 |
+
data_url = base64.b64encode(contents).decode("utf-8")
|
71 |
+
file_.close()
|
72 |
+
|
73 |
+
st.markdown(
|
74 |
+
f'<center><img src="data:image/gif;base64,{data_url}" class="centerImage" alt="cat gif"></center>',
|
75 |
+
unsafe_allow_html=True,
|
76 |
+
)
|
77 |
+
|
78 |
+
st.divider()
|
79 |
+
|
80 |
+
|
81 |
+
def support():
|
82 |
+
link = "https://www.paypal.com/paypalme/insilicochemistry"
|
83 |
+
file_ = open("data/support.png", "rb")
|
84 |
+
contents = file_.read()
|
85 |
+
data_url = base64.b64encode(contents).decode("utf-8")
|
86 |
+
file_.close()
|
87 |
+
st.markdown(
|
88 |
+
f'<center><a href="{link}"><img src="data:image/png;base64,{data_url}" class="centerImage" alt="cat gif"></center>',
|
89 |
+
unsafe_allow_html=True, )
|
90 |
+
|
91 |
+
|
92 |
+
def support_button():
|
93 |
+
url = "https://www.paypal.com/paypalme/insilicochemistry"
|
94 |
+
|
95 |
+
st.markdown(f'''
|
96 |
+
<a href={url}><button style="background-color:#a870dd;">Support us</button></a>
|
97 |
+
''',
|
98 |
+
unsafe_allow_html=True)
|
99 |
+
|
100 |
+
col1, col2, col3, col4, col5 = st.columns(5)
|
101 |
+
|
102 |
+
with col1:
|
103 |
+
pass
|
104 |
+
with col2:
|
105 |
+
pass
|
106 |
+
with col4:
|
107 |
+
pass
|
108 |
+
with col5:
|
109 |
+
pass
|
110 |
+
with col3:
|
111 |
+
|
112 |
+
st.link_button("**:white[Support us]**", "https://www.paypal.com/paypalme/insilicochemistry", type="primary")
|
113 |
+
|
114 |
+
|
115 |
+
with tab2:
|
116 |
+
# KETCHER
|
117 |
+
|
118 |
+
st.subheader("Drawing Arena")
|
119 |
+
molecule = st.text_input("Enter SMILES or Draw your Molecule :art:", "C1=C[SH]=CCO1")
|
120 |
+
smiles = st_ketcher(molecule, height=800)
|
121 |
+
stan_smiles = standardize_smiles(smiles)
|
122 |
+
|
123 |
+
#converter = NamesConverter(model_name="knowledgator/SMILES2IUPAC-canonical-base")
|
124 |
+
#st.code(converter.smiles_to_iupac(stan_smiles), "html")
|
125 |
+
st.code(stan_smiles, "html")
|
126 |
+
|
127 |
+
mol = Chem.MolFromSmiles(smiles)
|
128 |
+
s = Standardizer()
|
129 |
+
smol = s.standardize(mol)
|
130 |
+
|
131 |
+
|
132 |
+
# RENDERING
|
133 |
+
|
134 |
+
def render_2d(mol):
|
135 |
+
mol = Chem.MolFromSmiles(mol)
|
136 |
+
s = Standardizer()
|
137 |
+
smol = s.standardize(mol)
|
138 |
+
image = Draw.MolToImage(mol, size = (400, 400))
|
139 |
+
return image
|
140 |
+
|
141 |
+
|
142 |
+
def render_3d(smi):
|
143 |
+
mol = Chem.MolFromSmiles(smi)
|
144 |
+
|
145 |
+
if Hydrogen:
|
146 |
+
mol = Chem.AddHs(mol)
|
147 |
+
else:
|
148 |
+
pass
|
149 |
+
|
150 |
+
AllChem.EmbedMolecule(mol)
|
151 |
+
mblock = Chem.MolToMolBlock(mol)
|
152 |
+
|
153 |
+
xyzview = py3Dmol.view( width=400, height=400)
|
154 |
+
xyzview.addModel(mblock, 'mol')
|
155 |
+
|
156 |
+
|
157 |
+
xyzview.setStyle(stylemd, viewer=(0,0))
|
158 |
+
xyzview.setBackgroundColor(bcolor)
|
159 |
+
if box:
|
160 |
+
xyzview.addBox({'center': {'x': 0,'y': 0,'z': 0},
|
161 |
+
# 'dimensions': {'w': 1, 'h': 1, 'd': 1}, # scalars
|
162 |
+
'dimensions': {'w': {'x': 8, 'y': 8, 'z': 0}, #[1, 1, 0], #np.array([1,1,0]),
|
163 |
+
'h': {'x': 8, 'y': -8, 'z': 0}, # [1, -1, 0], #np.array([1,-1,0]),
|
164 |
+
'd': {'x': 0, 'y': 0, 'z': 8}, # [0, 0, 1], #np.array([0,0,1]),
|
165 |
+
},
|
166 |
+
'color': '#C791FB',
|
167 |
+
'alpha': 0.5,
|
168 |
+
})
|
169 |
+
else:
|
170 |
+
pass
|
171 |
+
xyzview.rotate(23, {'x': 1, 'y': 1, 'z': 1})
|
172 |
+
xyzview.zoomTo()
|
173 |
+
|
174 |
+
if spin:
|
175 |
+
xyzview.spin(True)
|
176 |
+
else:
|
177 |
+
xyzview.spin(False)
|
178 |
+
xyzview.setViewStyle({"style": "outline", "color": "#CA86FF", "width": 0.05})
|
179 |
+
#xyzview.addLabel(stan_smiles, {'position': {'x': -6.89, 'y': 0.75, 'z': 0.35},
|
180 |
+
# 'backgroundColor': '#515151', 'backgroundOpacity': 0.5,'fontSize':18,'fontColor':'#F9F7F7 ',
|
181 |
+
# 'fontOpacity':1,'borderThickness':0.0,'inFront':'true','showBackground':'true'})
|
182 |
+
|
183 |
+
showmol(xyzview,height=400,width=400)
|
184 |
+
|
185 |
+
blk2 = render_2d(smiles)
|
186 |
+
|
187 |
+
|
188 |
+
with tab3:
|
189 |
+
#st.code(converter.smiles_to_iupac(stan_smiles)[0], "html")
|
190 |
+
st.code(stan_smiles, "html")
|
191 |
+
col1, col2= st.columns((4,4))
|
192 |
+
with col1:
|
193 |
+
col1.subheader("2D STRUCTURE")
|
194 |
+
st.image(blk2)
|
195 |
+
with col2:
|
196 |
+
col2.subheader("3D STRUCTURE")
|
197 |
+
|
198 |
+
st.markdown("Select your Model!")
|
199 |
+
styles3d = {"Line Model": {"line": {}},
|
200 |
+
"Cross Model": {"cross":{}},
|
201 |
+
"Stick Model": {"stick": {}, "sphere": {"scale": 0}},
|
202 |
+
"Ball and Stick Model": {"stick": {}, "sphere": {"scale": 0.3}},
|
203 |
+
"CPK Model": {"sphere": {}}
|
204 |
+
}
|
205 |
+
list_style = ['Line', 'Cross', 'Stick', 'Ball and Stick', 'CPK']
|
206 |
+
value = ui.tabs(options=list_style, default_value='Line', key="kanaries")
|
207 |
+
|
208 |
+
|
209 |
+
def stylem(value):
|
210 |
+
if value == list_style[0]:
|
211 |
+
value2 = styles3d["Line Model"]
|
212 |
+
elif value == list_style[1]:
|
213 |
+
value2 = styles3d["Cross Model"]
|
214 |
+
elif value == list_style[2]:
|
215 |
+
value2 = styles3d["Stick Model"]
|
216 |
+
elif value == list_style[3]:
|
217 |
+
value2 = styles3d["Ball and Stick Model"]
|
218 |
+
elif value == list_style[4]:
|
219 |
+
value2 = styles3d["CPK Model"]
|
220 |
+
return value2
|
221 |
+
|
222 |
+
|
223 |
+
stylemd = stylem(value)
|
224 |
+
|
225 |
+
Hydrogen = st.toggle('Add Hydrogens', value=False, key=1)
|
226 |
+
|
227 |
+
spin = st.toggle('Animate', value=False, key=2)
|
228 |
+
box = st.toggle('Show Box', value=False, key=3)
|
229 |
+
bcolor = st.color_picker('Pick Background Color', '#323232', key=4)
|
230 |
+
render_3d(smiles)
|
231 |
+
|
232 |
+
with tab4:
|
233 |
+
st.subheader("**:gray[Representation and Format] :gray[Conversion]**")
|
234 |
+
|
235 |
+
datamol_mol = dm.to_mol(smiles)
|
236 |
+
#st.markdown(datamol_mol)
|
237 |
+
|
238 |
+
|
239 |
+
def to_smarts(datamol_mol):
|
240 |
+
smarts = dm.smiles_as_smarts(datamol_mol)
|
241 |
+
st.code(smarts, "html")
|
242 |
+
|
243 |
+
|
244 |
+
def to__inchi(datamol_mol):
|
245 |
+
inchi = dm.to_inchi(datamol_mol)
|
246 |
+
st.code(inchi, "html")
|
247 |
+
|
248 |
+
|
249 |
+
def to__inchikey(datamol_mol):
|
250 |
+
inchikey = dm.to_inchikey(datamol_mol)
|
251 |
+
st.code(inchikey, "html")
|
252 |
+
|
253 |
+
|
254 |
+
def to_xyz(smiles, unsafe_allow_html=True):
|
255 |
+
mol = Chem.MolFromSmiles(smiles)
|
256 |
+
mol_h = Chem.AddHs(mol)
|
257 |
+
AllChem.EmbedMolecule(mol_h)
|
258 |
+
xyz = Chem.MolToXYZBlock(mol_h)
|
259 |
+
mol2 = Chem.MolFromXYZBlock(xyz)
|
260 |
+
rdDetermineBonds.DetermineBonds(mol2)
|
261 |
+
xyz = Chem.MolToXYZBlock(mol2)
|
262 |
+
st.code(xyz,"html")
|
263 |
+
st.download_button(label="Download .xyz File", data=xyz,
|
264 |
+
file_name=f'{stan_smiles}' + "." + "xyz", mime='text/csv', )
|
265 |
+
|
266 |
+
|
267 |
+
def to_rdkit3d(smiles):
|
268 |
+
mol = Chem.MolFromSmiles(smiles)
|
269 |
+
mol_h = Chem.AddHs(mol)
|
270 |
+
AllChem.EmbedMolecule(mol_h)
|
271 |
+
xyz = Chem.MolToXYZBlock(mol_h)
|
272 |
+
mol2 = Chem.MolFromXYZBlock(xyz)
|
273 |
+
rdDetermineBonds.DetermineBonds(mol2)
|
274 |
+
xyz = Chem.MolToXYZBlock(mol2)
|
275 |
+
input_geom_str = xyz
|
276 |
+
mol2 = pybel.readstring("xyz", input_geom_str)
|
277 |
+
# mol.make3D()
|
278 |
+
output_geom_str = mol2.write("mol")
|
279 |
+
st.code(output_geom_str,"html")
|
280 |
+
st.download_button(label="Download .mol File", data=output_geom_str,
|
281 |
+
file_name=f'{stan_smiles}' + "." + "mol", mime='text/csv', )
|
282 |
+
|
283 |
+
def to_sdf(smiles):
|
284 |
+
mol = Chem.MolFromSmiles(smiles)
|
285 |
+
mol_h = Chem.AddHs(mol)
|
286 |
+
AllChem.EmbedMolecule(mol_h)
|
287 |
+
xyz = Chem.MolToXYZBlock(mol_h)
|
288 |
+
mol2 = Chem.MolFromXYZBlock(xyz)
|
289 |
+
rdDetermineBonds.DetermineBonds(mol2)
|
290 |
+
xyz = Chem.MolToXYZBlock(mol2)
|
291 |
+
input_geom_str = xyz
|
292 |
+
mol2 = pybel.readstring("xyz", input_geom_str)
|
293 |
+
# mol.make3D()
|
294 |
+
output_geom_str = mol2.write("sdf")
|
295 |
+
st.code(output_geom_str,"html")
|
296 |
+
st.download_button(label="Download .sdf File", data=output_geom_str,
|
297 |
+
file_name=f'{stan_smiles}' + "." + "sdf", mime='text/csv', )
|
298 |
+
|
299 |
+
def to_cif(smiles):
|
300 |
+
mol = Chem.MolFromSmiles(smiles)
|
301 |
+
mol_h = Chem.AddHs(mol)
|
302 |
+
AllChem.EmbedMolecule(mol_h)
|
303 |
+
xyz = Chem.MolToXYZBlock(mol_h)
|
304 |
+
mol2 = Chem.MolFromXYZBlock(xyz)
|
305 |
+
rdDetermineBonds.DetermineBonds(mol2)
|
306 |
+
xyz = Chem.MolToXYZBlock(mol2)
|
307 |
+
input_geom_str = xyz
|
308 |
+
mol2 = pybel.readstring("xyz", input_geom_str)
|
309 |
+
# mol.make3D()
|
310 |
+
output_geom_str = mol2.write("cif")
|
311 |
+
st.code(output_geom_str,"html")
|
312 |
+
st.download_button(label="Download .cif File", data=output_geom_str,
|
313 |
+
file_name=f'{stan_smiles}' + "." + "cif", mime='text/csv', )
|
314 |
+
|
315 |
+
|
316 |
+
def to_pdb(smiles):
|
317 |
+
mol = Chem.MolFromSmiles(smiles)
|
318 |
+
mol_h = Chem.AddHs(mol)
|
319 |
+
AllChem.EmbedMolecule(mol_h)
|
320 |
+
xyz = Chem.MolToXYZBlock(mol_h)
|
321 |
+
mol2 = Chem.MolFromXYZBlock(xyz)
|
322 |
+
rdDetermineBonds.DetermineBonds(mol2)
|
323 |
+
xyz = Chem.MolToXYZBlock(mol2)
|
324 |
+
input_geom_str = xyz
|
325 |
+
mol2 = pybel.readstring("xyz", input_geom_str)
|
326 |
+
# mol.make3D()
|
327 |
+
output_geom_str = mol2.write("pdb")
|
328 |
+
st.code(output_geom_str,"html")
|
329 |
+
st.download_button(label="Download .pdb File", data=output_geom_str,
|
330 |
+
file_name=f'{stan_smiles}' + "." + "pdb", mime='text/csv', )
|
331 |
+
|
332 |
+
|
333 |
+
SMILES_OUT = st.selectbox("Select Output!",["SMARTS", "InChI", "InChIKey", "mol", "sdf", "xyz", "cif", "pdb"])
|
334 |
+
|
335 |
+
if SMILES_OUT == "SMARTS":
|
336 |
+
to_smarts(datamol_mol)
|
337 |
+
elif SMILES_OUT == "InChI":
|
338 |
+
to__inchi(datamol_mol)
|
339 |
+
elif SMILES_OUT == "InChIKey":
|
340 |
+
to__inchikey(datamol_mol)
|
341 |
+
elif SMILES_OUT == "xyz":
|
342 |
+
to_xyz(smiles, unsafe_allow_html=True)
|
343 |
+
elif SMILES_OUT == "mol":
|
344 |
+
to_rdkit3d(smiles)
|
345 |
+
elif SMILES_OUT == "sdf":
|
346 |
+
to_sdf(smiles)
|
347 |
+
elif SMILES_OUT == "cif":
|
348 |
+
to_cif(smiles)
|
349 |
+
elif SMILES_OUT == "pdb":
|
350 |
+
to_pdb(smiles)
|
351 |
+
|
352 |
+
|
353 |
+
|
354 |
+
with tab5:
|
355 |
+
|
356 |
+
my_dict = {'SMILES': stan_smiles,
|
357 |
+
'Molecular Weight': Descriptors.MolWt(smol),
|
358 |
+
'Number of H Acceptors': Descriptors.NumHAcceptors(smol),
|
359 |
+
'Number of H Donors': Descriptors.NumHDonors(smol),
|
360 |
+
'Octanol/Water Partition Coefficient LogP': Descriptors.MolLogP(smol),
|
361 |
+
"Topological Polar Surface Area (TPSA)": Descriptors.TPSA(smol),
|
362 |
+
"Lipinski's Rule of 5": mc.rules.basic_rules.rule_of_five(datamol_mol),
|
363 |
+
"Pfizer Rule 3/75": mc.rules.basic_rules.rule_of_pfizer_3_75(datamol_mol)
|
364 |
+
}
|
365 |
+
|
366 |
+
|
367 |
+
new = pd.DataFrame.from_dict([my_dict],)
|
368 |
+
new = new.rename(index={0: 'Descriptors and Rules'})
|
369 |
+
NEWT = new.T
|
370 |
+
st.dataframe(NEWT)
|
371 |
+
NEWT = NEWT.to_csv(index=True).encode('utf-8')
|
372 |
+
st.download_button(
|
373 |
+
"Download data!",
|
374 |
+
NEWT,
|
375 |
+
f"{stan_smiles}"+" Descriptors_Rules"+".csv",
|
376 |
+
"text/csv",
|
377 |
+
key='download-csv'
|
378 |
+
)
|
379 |
+
|
380 |
+
|
data/baa.gif
ADDED
![]() |
Git LFS Details
|
data/banner.png
ADDED
![]() |
data/banner24.png
ADDED
![]() |
data/favicon.png
ADDED
![]() |
data/speck.png
ADDED
![]() |
data/speck24.png
ADDED
![]() |
environment_backup.yml
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: streamlit-conda-minimal
|
2 |
+
channels:
|
3 |
+
- conda-forge
|
4 |
+
- anaconda
|
5 |
+
dependencies:
|
6 |
+
- streamlit
|
7 |
+
- openbabel
|
8 |
+
- py3Dmol
|
9 |
+
- ipython
|
10 |
+
- ase
|
packages.txt
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
openbabel
|
2 |
+
libopenbabel-dev
|
requirements.txt
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
datamol==0.12.2
|
2 |
+
ipyspeck==0.6.1
|
3 |
+
matplotlib==3.7.1
|
4 |
+
medchem==2.0.3
|
5 |
+
MolVS==0.1.1
|
6 |
+
numpy==1.24.3
|
7 |
+
pandas==1.5.3
|
8 |
+
Pillow==9.4.0
|
9 |
+
py3Dmol==2.0.4
|
10 |
+
pyperclip==1.8.2
|
11 |
+
rdkit==2023.9.1
|
12 |
+
st_speckmol==0.0.6
|
13 |
+
stmol==0.0.9
|
14 |
+
streamlit
|
15 |
+
streamlit_ketcher==0.0.1
|
16 |
+
streamlit_scrollable_textbox==0.0.3
|
17 |
+
streamlit_shadcn_ui==0.1.18
|
18 |
+
ipython_genutils==0.1.0
|
19 |
+
openbabel-wheel
|
20 |
+
ipython
|
your_molecule.py
ADDED
@@ -0,0 +1,180 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
from streamlit_ketcher import st_ketcher
|
3 |
+
from rdkit import Chem
|
4 |
+
from rdkit.Chem import Draw, AllChem, rdDetermineBonds, Descriptors
|
5 |
+
|
6 |
+
import py3Dmol
|
7 |
+
from stmol import showmol
|
8 |
+
from io import StringIO
|
9 |
+
import sys
|
10 |
+
import subprocess
|
11 |
+
import time
|
12 |
+
import streamlit_shadcn_ui as ui
|
13 |
+
import streamlit_shadcn_ui as ui
|
14 |
+
|
15 |
+
|
16 |
+
try:
|
17 |
+
# from openbabel import OBMol, OBConversion
|
18 |
+
import openbabel
|
19 |
+
except ModuleNotFoundError as e:
|
20 |
+
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)
|
21 |
+
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)
|
22 |
+
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)
|
23 |
+
# wait for subprocess to install package before running your actual code below
|
24 |
+
#print('openbabel python not importing')
|
25 |
+
time.sleep(90)
|
26 |
+
|
27 |
+
from openbabel import pybel
|
28 |
+
|
29 |
+
|
30 |
+
st.set_page_config(page_title="CHEMSTUDIO24", page_icon="data/favicon.png", layout="centered")
|
31 |
+
st.logo("data/banner24.png")
|
32 |
+
|
33 |
+
st.write("# **:gray[Your] :rainbow[Molecule] :gray[playground]**")
|
34 |
+
st.markdown((":gray[Visualize and Convert your] :rainbow[Molecule]"))
|
35 |
+
|
36 |
+
supported_input_formats = ['xyz', 'cif', 'pdb','mol', 'mol2','sdf', 'tmol', 'poscar','cub','cube','mcif','mmcif', 'pwscf','smi']
|
37 |
+
supported_output_formats = ['cif', 'tmol', 'xyz', 'sdf','pdb','smiles', 'cube','mcif','mmcif','mdl','mol','mol2','smi',]
|
38 |
+
|
39 |
+
data = '''12
|
40 |
+
|
41 |
+
C 1.525098 0.401299 -0.169919
|
42 |
+
C 1.267282 -0.890923 -0.090842
|
43 |
+
S -0.375869 -1.429467 -0.350672
|
44 |
+
C -1.364069 -0.186583 -0.232712
|
45 |
+
C -0.787332 1.146673 0.059053
|
46 |
+
O 0.519018 1.327928 -0.452149
|
47 |
+
H 2.534310 0.743140 -0.012656
|
48 |
+
H 2.085372 -1.592058 0.136539
|
49 |
+
H -0.704143 -2.346960 0.640753
|
50 |
+
H -2.462024 -0.305561 -0.365090
|
51 |
+
H -0.753918 1.233523 1.179450
|
52 |
+
H -1.483725 1.898990 -0.341753
|
53 |
+
'''
|
54 |
+
|
55 |
+
# st.components.v1.iframe("https://pubchem.ncbi.nlm.nih.gov/periodic-table/#view=table&embed=true", width=800, height=800, scrolling=True)
|
56 |
+
col1, col2 = st.columns(2)
|
57 |
+
col1.write('## Input Molecule')
|
58 |
+
input_format = col1.selectbox('Firstly, select the input file format',
|
59 |
+
supported_input_formats, )
|
60 |
+
|
61 |
+
input_text_area = col1.empty()
|
62 |
+
uploaded_file = col1.file_uploader("or Choose a file from your local data")
|
63 |
+
if uploaded_file is not None:
|
64 |
+
# To read file as bytes:
|
65 |
+
bytes_data = uploaded_file.getvalue()
|
66 |
+
|
67 |
+
#uploaded_file_name = uploaded_file.name.split(".")
|
68 |
+
#input_up_format = uploaded_file_name[-1]
|
69 |
+
|
70 |
+
|
71 |
+
# To convert to a string based IO:
|
72 |
+
stringio = StringIO(uploaded_file.getvalue().decode("utf-8"))
|
73 |
+
|
74 |
+
# To read file as string:
|
75 |
+
string_data = stringio.read()
|
76 |
+
placeholder_xyz_str = string_data
|
77 |
+
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)
|
78 |
+
|
79 |
+
elif uploaded_file is None:
|
80 |
+
|
81 |
+
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')
|
82 |
+
# # Get rid of empty lines
|
83 |
+
# input_geom_str = os.linesep.join([s for s in input_geom_str.splitlines() if s])
|
84 |
+
|
85 |
+
mol = pybel.readstring(input_format, input_geom_str)
|
86 |
+
# mol.make3D()
|
87 |
+
|
88 |
+
|
89 |
+
|
90 |
+
## OUTPUT ##
|
91 |
+
col2.write('## Output')
|
92 |
+
output_format = col2.selectbox('Select the output file format',
|
93 |
+
supported_output_formats)
|
94 |
+
output_geom_str = mol.write(output_format)
|
95 |
+
col2.text_area(label='Converted file structure', value=output_geom_str, height=400)
|
96 |
+
col2.download_button(
|
97 |
+
label="Download the output",
|
98 |
+
data=output_geom_str,
|
99 |
+
file_name='your_new_output.'+output_format,
|
100 |
+
mime='text/csv',)
|
101 |
+
|
102 |
+
st.divider()
|
103 |
+
|
104 |
+
st.subheader("Visualization Scene")
|
105 |
+
col3, col4 = st.columns(2)
|
106 |
+
|
107 |
+
|
108 |
+
def vis_your_molecule():
|
109 |
+
newviewer = py3Dmol.view(width=400, height=400)
|
110 |
+
structure_for_visualization = ''
|
111 |
+
try:
|
112 |
+
mol = pybel.readstring(input_format, input_geom_str)
|
113 |
+
# mol.make3D()
|
114 |
+
|
115 |
+
structure_for_visualization = mol.write('xyz')
|
116 |
+
except Exception as e:
|
117 |
+
print('There was a problem with the conversion', e)
|
118 |
+
|
119 |
+
newviewer.addModel(structure_for_visualization, 'xyz')
|
120 |
+
newviewer.setBackgroundColor(bcolor2)
|
121 |
+
|
122 |
+
newviewer.setStyle(stylemd2)
|
123 |
+
newviewer.setViewStyle({"style": "outline", "color": "#CA86FF", "width": 0.05})
|
124 |
+
|
125 |
+
if spin2:
|
126 |
+
newviewer.spin(True)
|
127 |
+
else:
|
128 |
+
newviewer.spin(False)
|
129 |
+
|
130 |
+
if box2:
|
131 |
+
newviewer.addBox({'center': {'x': 0,'y': 0,'z': 0},
|
132 |
+
# 'dimensions': {'w': 1, 'h': 1, 'd': 1}, # scalars
|
133 |
+
'dimensions': {'w': {'x': 8, 'y': 8, 'z': 0}, #[1, 1, 0], #np.array([1,1,0]),
|
134 |
+
'h': {'x': 8, 'y': -8, 'z': 0}, # [1, -1, 0], #np.array([1,-1,0]),
|
135 |
+
'd': {'x': 0, 'y': 0, 'z': 8}, # [0, 0, 1], #np.array([0,0,1]),
|
136 |
+
},
|
137 |
+
'color': '#C791FB',
|
138 |
+
'alpha': 0.5,
|
139 |
+
})
|
140 |
+
else:
|
141 |
+
pass
|
142 |
+
|
143 |
+
showmol(newviewer,height=400,width=400)
|
144 |
+
|
145 |
+
with col3:
|
146 |
+
|
147 |
+
st.markdown("Select your Model!")
|
148 |
+
styles3d2 = {"Line Model": {"line": {}},
|
149 |
+
"Cross Model": {"cross":{}},
|
150 |
+
"Stick Model": {"stick": {}, "sphere": {"scale": 0}},
|
151 |
+
"Ball and Stick Model": {"stick": {}, "sphere": {"scale": 0.3}},
|
152 |
+
"CPK Model": {"sphere": {}}
|
153 |
+
}
|
154 |
+
list_style2 = ['Line', 'Cross', 'Stick', 'Ball and Stick', 'CPK']
|
155 |
+
value2 = ui.tabs(options=list_style2, default_value='Line', key="flowers")
|
156 |
+
|
157 |
+
spin2 = st.toggle('Animate', value=False, key=5)
|
158 |
+
box2 = st.toggle('Show Box', value=False, key=6)
|
159 |
+
bcolor2 = st.color_picker('Pick Background Color', '#323232', key=7)
|
160 |
+
|
161 |
+
def stylem2(value2):
|
162 |
+
if value2 == list_style2[0]:
|
163 |
+
value4 = styles3d2["Line Model"]
|
164 |
+
elif value2 == list_style2[1]:
|
165 |
+
value4 = styles3d2["Cross Model"]
|
166 |
+
elif value2 == list_style2[2]:
|
167 |
+
value4 = styles3d2["Stick Model"]
|
168 |
+
elif value2 == list_style2[3]:
|
169 |
+
value4 = styles3d2["Ball and Stick Model"]
|
170 |
+
elif value2 == list_style2[4]:
|
171 |
+
value4 = styles3d2["CPK Model"]
|
172 |
+
return value4
|
173 |
+
|
174 |
+
|
175 |
+
stylemd2 = stylem2(value2)
|
176 |
+
|
177 |
+
|
178 |
+
|
179 |
+
with col4:
|
180 |
+
vis_your_molecule()
|