# Is converting SMARTS to SMILES a "lossless" operation?

The following three different SMARTS strings represent the same structure - at least when depicting it (e.g. at Uni Hamburg Smarts viewer).

SMARTS:
[#6]-1=[#6]-[#6](-[#6]-[#6](-[#6]-1)-[#6])=[#8]
[#6]-1-[#6]=[#6]-[#6](-[#6]-[#6]-1-[#6])=[#8]
[#6]-1-[#6](-[#6]=[#6]-[#6]-[#6]-1-[#6])=[#8]


Also, the chemical structure represented in SMILES leads to only one string, at least only one I can think of.

SMILES:
CC1CC=CC(=O)C1


Now, I do know the differences between SMARTS and SMILES, and I do know what the symbols in SMARTS mean. Still, I tried several softwares to find any differences in the use between SMARTS and SMILES representation for that specific case, and couldn't find any.

So I wonder if I could use SMILES in that case, or if there's any danger of missing information, for example when searching for substructures?

SMARTS is deliberately designed to be a superset of SMILES. That is, any valid SMILES depiction should also be a valid SMARTS query, one that will retrieve the very structure that the SMILES string depicts.

However, as a query language, SMARTS can be more general than SMILES is. For example, CC as a SMILES string depicts a single compound: ethane. As a SMARTS query, though, CC will match ethane, but will also match propane, acetic acid, cyclohexane, vancomycin, etc.

There's also SMARTS strings which are not valid SMILES strings. You list several in your question: [#6]-1=[#6]-[#6](-[#6]-[#6](-[#6]-1)-[#6])=[#8] is not a valid SMILES representation, unless your SMILES parser is being particularly generous. Even if it is, [#6]-1=[#6]-[#6](-[#6]-[#6](-[#6]-1)-[#6])=[#8,#7] is also a valid SMARTS query which should match your molecule, but not even a generous SMILES parser is likely to accept it.

Despite being similar, SMARTS and SMILES are intended for fundamentally different things - the purpose of SMILES is to represent particular compounds, whereas SMARTS represents a query against a range of possible molecules, or an abstract description of a set of possible molecules. As such, they're not inter-convertible, even if the strings are literally identical.

For your particular case, yes, CC1CC=CC(=O)C1 is both a valid SMILES and a valid SMARTS, but as a SMARTS query, it represents not just 5-methyl-2-cyclohexen-1-one, but also 5-propyl-2-cyclohexen-1-one and 3-hydroxy-5-butyl-6-amino-2-cyclohexen-1-one, as well as many others, all of which contain that substructure. The SMARTS viewer you link doesn't depict this explicitly, because it's implicit in the use of SMARTS that it's a substructure pattern for a broader class of compounds.

Thilo asked a similar question on the rdkit-discuss mailing list, where Andrew Dalke chimed in with this response, which he gave me permission to post here. The answer uses the python-based rdkit library to give examples of converting between SMILES and SMARTS and other tasks.

From Andrew Dalke:

On Apr 19, 2017, at 12:03, Thilo Bauer wrote:

Is converting SMARTS to SMILES a "lossless" operation, or does one loose information on doing so?

It is obviously not lossless if you include terms that cannot be represented in SMILES.

>>> from rdkit import Chem
>>> Chem.MolToSmiles(Chem.MolFromSmarts("[C,N]"))
'C'


or which don't make sense as a molecule:

>>> Chem.MolToSmiles(Chem.MolFromSmarts("c"))
'c'
>>> Chem.MolFromSmiles("c")
[23:02:24] non-ring atom 0 marked aromatic


It also loses some information which could be represented in SMILES:

>>> Chem.MolToSmiles(Chem.MolFromSmarts("[NH4+]"))
'N'
>>> Chem.MolToSmiles(Chem.MolFromSmarts("C[N+]1(C)CCCCC1"))
'CN1(C)CCCCC1'
>>> Chem.MolToSmiles(Chem.MolFromSmarts("[12C]"), isomericSmiles=True)
'C'


Do be careful if you want to handle aromatic atoms and bonds:

>>> Chem.MolToSmiles(Chem.MolFromSmarts("[#6]:1:[#6]:[#6]:[#6]:[#6]:[#6]:1"))
'C1:C:C:C:C:C:1'
>>> Chem.MolToSmiles(Chem.MolFromSmarts("c=1-c=c-c=c-c=1"))
'c1=c-c=c-c=c-1'


Background: I've got three different SMARTS strings representing the same structure - at least when depicting it. Also all three strings result in the exact same SMILES (see code and output below).

It looks like you want SMARTS canonicalization.

In general this is hard, because SMARTS can include boolean expressions and recursive SMARTS.

If you limit yourself to patterns like '[#6]-1=[#6]-[#6]...', with only atomic numbers and single/double/triple bonds, then I think RDKit will do what you want.

From chemistry stack exchange, an answer contributed by user R.M.:

SMARTS is deliberately designed to be a superset of SMILES. That is, any valid SMILES depiction should also be a valid SMARTS query, one that will retrieve the very structure that the SMILES string depicts.

Except, that last clause isn't true. Try matching tritium against itself.

>>> from rdkit import Chem
>>> mol = Chem.MolFromSmiles("[3H]")
>>> pat = Chem.MolFromSmarts("[3H]")
>>> mol.HasSubstructMatch(pat)
False


For hydrogens you must use '#1', because H in SMARTS means something different.

>>> pat2 = Chem.MolFromSmarts("[3#1]")
>>> mol.HasSubstructMatch(pat2)
True


SMILES input under Daylight and most other toolkits gets normalized to the chemistry model, including aromaticity perception:

>>> mol = Chem.MolFromSmiles("C1=CC=CC=C1")
>>> pat = Chem.MolFromSmarts("C1=CC=CC=C1")
>>> mol.HasSubstructMatch(pat)
False
>>> pat2 = Chem.MolFromSmarts("c1ccccc1")
>>> mol.HasSubstructMatch(pat2)
True


RDKit also does a small amount of additional normalization, or 'sanitization' to use the RDKit term. For example, it will convert "neutral 5 coordinate Ns with double bonds to Os to the zwitterionic form" (see GraphMol/MolOps.cpp):

>>> s = "CN(=O)=O"
>>> mol = Chem.MolFromSmiles(s)
>>> pat = Chem.MolFromSmarts(s)
>>> mol.HasSubstructMatch(pat)
False
>>> Chem.MolToSmiles(mol)
'C[N+](=O)[O-]'


I believe that the output SMILES from a toolkit, assuming that the SMILES doesn't have an explicit hydrogen, can be used a SMARTS which will match the molecule made from that same SMILES, by that same toolkit.

• Thank you very much for the detailed answer and for posting the mailing list result here! The examples provided here clarify a lot. Apr 20 '17 at 7:18

In this case, the SMARTS and SMILES represent the same (sub)-structure, in particular because the SMARTS pattern explicitly defines the single atom type and connectivity for all atoms. So to answer your question, yes, this case is a lossless conversion.

In contrast, if the O could be an O or an N, the SMARTS would not catch that. And this both your SMILES and SMARTS would miss N=C1C=CCC(C)C1. However, you can write a SMARTS to match both N=C1C=CCC(C)C1 and O=C1C=CCC(C)C1, but a SMILES will not.

Also, note that the SMILES could be written in many (equivalent) ways, e.g., O=C1C=CCC(C)C1