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

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

Wolfram’s function for
GET
calls is the
URLRead
function.
In[]:=
URLRead["https://smilesdb.org/api/smiles/random/10"]
Out[]=
HTTPResponse
Status: OK
Content type: application/json

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)NCc1c(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)nc2cc3OCCOc3cc12","CC1(C)O[C@@H]2O[C@@H]3[C@@H](ON=C3CO)[C@@H]2O1","NC(=O)N1c2ccccc2C=Cc2ccccc12","COc1c(CN)cc(CN)cc1OCCCN1Cc2ccccc2C1","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

Now that we have SMILES strings, we can use Wolfram’s robust Chemistry interface.
Mapping
Molecule
to the list of SMILES strings:
In[]:=
mols=Molecule/@parsed;
In[]:=
ListAnimate[mols]
Out[]=
Molecule
Formula:
2-
C
14
H
9
N
O
4
Atoms:
28
Bonds:
29


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[]=
{LogP3.4214,SMILESCC(C)CCN1C(C)C(=O)N(C)c2cnc(Nc3cc(F)c(O)c(F)c3)nc12,TPSA81.59,formulaC19H23F2N5O2,hbond_acceptors6,hbond_donors2,num_atoms28,num_bonds30,rotatable_bonds5,weight391.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[]=
391.42
u
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

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

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
Formula:
C
20
H
12
BrCl
N
4
O
Atoms:
39
Bonds:
43
,Molecule
Formula:
C
16
H
9
Br
5
ClN
O
4
Atoms:
36
Bonds:
37
,Molecule
Formula:
C
21
H
17
Cl
F
2
N
4
O
2
Atoms:
47
Bonds:
50

In[]:=
getShortest[n_Integer]:=Molecule/@ImportString[URLRead["https://smilesdb.org/api/smiles/short/"<>ToString[n],"Body"],"JSON"]
In[]:=
getShortest[3]
Out[]=
Molecule
Formula:
C
7
H
8
Atoms:
15
Bonds:
15
,Molecule
Formula:
C
7
H
8
Atoms:
15
Bonds:
15
,Molecule
Formula:
C
7
H
8
Atoms:
15
Bonds:
15

In[]:=
getLongest[n_Integer]:=Molecule/@ImportString[URLRead["https://smilesdb.org/api/smiles/long/"<>ToString[n],"Body"],"JSON"]
In[]:=
getLongest[3]
Out[]=
Molecule
Formula:
C
202
H
345
N
55
O
64
S
Atoms:
667
Bonds:
669
,Molecule
Formula:
C
222
H
366
N
66
O
68
S
7
Atoms:
729
Bonds:
734
,Molecule
Formula:
C
253
H
407
N
73
O
72
S
8
Atoms:
813
Bonds:
821

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

Interfacing with SmilesDB in Wolfram​
by William Choi-Kim​
Wolfram Community, STAFF PICKS, November 25, 2024
​https://community.wolfram.com/groups/-/m/t/3327619