While working on my WELP project, I recently created a database of over 5,000 SMILES strings compiled from across the internet and released it as a free API (https://smilesdb.org). There weren’t any accessibly databases like this, so I wanted to try using it with Wolfram to gauge some possible future applications and where I might take it from here.
Background
Background
SMILES strings are a once-propriety (now open) standard for storing molecular structures in compact strings. They’re incredibly portable and human-readable, which makes them one of the predominant ways of communicating chemical information. Oddly, SMILES string databases aren’t very common. In fact, while working on my WELP project, I found... none. There were databases with chemicals that had SMILES string information, but there was no way to get the SMILE strings alone efficiently.
So in the spirit of programming, I spent a month building an open-source API to do automatically what I could have done in about an hour by hand. Most of the molecule data is sourced from BindingDB and ChemBL (licensed Share-Alike). Now that I’ve spent all that time on this database, I’d like to play around with it a little bit in Wolfram. Wolfram’s Chemistry interface is very receptive to SMILES strings, so all we need to do is query the API and feed that straight in Wolfram.
URLRead
URLRead
Wolfram’s function for calls is the function.
GET
URLRead
In[]:=
URLRead["https://smilesdb.org/api/smiles/random/10"]
Out[]=
HTTPResponse
We want the body of the response so we add that as an argument:
In[]:=
result=URLRead["https://smilesdb.org/api/smiles/random/10","Body"]
Out[]=
["CC[C@H](C)CN(C[C@@H](O)[C@H](Cc1ccccc1)NC(=O)O[C@H]1CO[C@H]2OCC[C@@H]12)S(=O)(=O)c1ccc(N)cc1","OC(=O)COc1cc(Cl)ccc1C(=O)NCc1c(Br)c(Br)c(Br)c(Br)c1Br","[O-]C(=O)c1ccccc1Nc1ccccc1C([O-])=O","O=C(Nc1n[nH]c2nnc(cc12)-c1cccnc1)C1CC1","COc1ccc(cc1)C(=O)n1c(SC)nc2cc3OCCOc3cc12","CC1(C)O[C@@H]2O[C@@H]3[C@@H](ON=C3CO)[C@@H]2O1","NC(=O)N1c2ccccc2C=Cc2ccccc12","COc1c(CN)cc(CN)cc1OCCCN1Cc2ccccc2C1","C1CCN[c+]2ccn(CCCCCn3cc[c+](NCC1)c1ccccc31)c1ccccc21","OC(=O)C(=O)CS(O)(=O)=O"]
This isn’t a Wolfram list, it’s just a JSON string right now.
To parse it, we call :
ImportString
In[]:=
parsed=ImportString[result,"JSON"]
Out[]=
{CC[C@H](C)CN(C[C@@H](O)[C@H](Cc1ccccc1)NC(=O)O[C@H]1CO[C@H]2OCC[C@@H]12)S(=O)(=O)c1ccc(N)cc1,OC(=O)COc1cc(Cl)ccc1C(=O)NCc1c(Br)c(Br)c(Br)c(Br)c1Br,[O-]C(=O)c1ccccc1Nc1ccccc1C([O-])=O,O=C(Nc1n[nH]c2nnc(cc12)-c1cccnc1)C1CC1,COc1ccc(cc1)C(=O)n1c(SC)nc2cc3OCCOc3cc12,CC1(C)O[C@@H]2O[C@@H]3[C@@H](ON=C3CO)[C@@H]2O1,NC(=O)N1c2ccccc2C=Cc2ccccc12,COc1c(CN)cc(CN)cc1OCCCN1Cc2ccccc2C1,C1CCN[c+]2ccn(CCCCCn3cc[c+](NCC1)c1ccccc31)c1ccccc21,OC(=O)C(=O)CS(O)(=O)=O}
Chemistry Interface
Chemistry Interface
Now that we have SMILES strings, we can use Wolfram’s robust Chemistry interface.
Mapping to the list of SMILES strings:
Molecule
In[]:=
mols=Molecule/@parsed;
In[]:=
ListAnimate[mols]
Out[]=
RDKit Data
RDKit Data
The API also features other data compiled from running RDKit analysis on the database, so we can play with those features.
In[]:=
data=ImportString[URLRead["https://smilesdb.org/api/random/10","Body"],"JSON"];
We can take a look at one of the molecules the API returns.
In[]:=
data[[1]]
Out[]=
{LogP3.4214,SMILESCC(C)CCN1C(C)C(=O)N(C)c2cnc(Nc3cc(F)c(O)c(F)c3)nc12,TPSA81.59,formulaC19H23F2N5O2,hbond_acceptors6,hbond_donors2,num_atoms28,num_bonds30,rotatable_bonds5,weight391.422}
We can plot the molecule to see if there’s any differences in how Wolfram interprets it.
In[]:=
mol1dat=Association[data[[1]]];mol1=Molecule[mol1dat["SMILES"]];
With the power of :
MoleculePlot3D
In[]:=
MoleculePlot3D[mol1]
Out[]=
The API and Wolfram agree on most things:
In[]:=
MoleculeValue[mol1,"RotatableBondCount"]
Out[]=
5
In[]:=
MoleculeValue[mol1,"HBondAcceptorCount"]
Out[]=
6
In[]:=
MoleculeValue[mol1,"HBondDonorCount"]
Out[]=
2
In[]:=
MoleculeValue[mol1,"MolecularMass"]
Out[]=
But they disagree, oddly, on the number of atoms and the number of bonds. I suspect this is due to implicit hydrogens.
In[]:=
Length[MoleculeValue[mol1,"AtomList"]]
Out[]=
51
In[]:=
Length[MoleculeValue[mol1,"BondList"]]
Out[]=
53
Application
Application
The predominant envisioned application of this API is the application for which I created it - as a source of test cases for various chemistry packages. Chemical formulas aren’t useful in determining molecular geometry, and when building packages, it’s tiresome and often impossible to create test cases by hand.
SmilesDB is meant to solve that problem - just query the endpoint, get anywhere from 1 to 5,479 molecules, and do as you please!
Generalization
Generalization
We’ll wrap up this short essay with a simple generalized set of functions for SmilesDB.
In[]:=
getRandom[n_Integer]:=Molecule/@ImportString[URLRead["https://smilesdb.org/api/smiles/random/"<>ToString[n],"Body"],"JSON"]
In[]:=
getRandom[3]
Out[]=
Molecule,Molecule,Molecule
In[]:=
getShortest[n_Integer]:=Molecule/@ImportString[URLRead["https://smilesdb.org/api/smiles/short/"<>ToString[n],"Body"],"JSON"]
In[]:=
getShortest[3]
Out[]=
Molecule,Molecule,Molecule
In[]:=
getLongest[n_Integer]:=Molecule/@ImportString[URLRead["https://smilesdb.org/api/smiles/long/"<>ToString[n],"Body"],"JSON"]
In[]:=
getLongest[3]
Out[]=
Molecule,Molecule,Molecule
If you’d like to play around with the API yourself, it’s freely available at https://smilesdb.org. You can read the documentation at https://smilesdb.org/docs.
CITE THIS NOTEBOOK
CITE THIS NOTEBOOK
Interfacing with SmilesDB in Wolfram
by William Choi-Kim
Wolfram Community, STAFF PICKS, November 25, 2024
https://community.wolfram.com/groups/-/m/t/3327619
by William Choi-Kim
Wolfram Community, STAFF PICKS, November 25, 2024
https://community.wolfram.com/groups/-/m/t/3327619