How to calculate the number of hydrogen atoms from SMILES string?
For example,
SMILES String: C1=CC(=C(C=C1C(CN)O)O)O
The known result is C8H11NO3
Chemistry Stack Exchange is a question and answer site for scientists, academics, teachers, and students in the field of chemistry. It only takes a minute to sign up.
Sign up to join this communityHow to calculate the number of hydrogen atoms from SMILES string?
For example,
SMILES String: C1=CC(=C(C=C1C(CN)O)O)O
The known result is C8H11NO3
Other answers have done a good job of providing a description of the concepts and algorithms needed to answer the question. Here I'll demonstrate the opposite: a black-box empirical approach.
In Python using rdkit
:
from rdkit import Chem
from rdkit.Chem import rdMolDescriptors
my_smiles_string = 'C1=CC(=C(C=C1C(CN)O)O)O'
my_mol = Chem.MolFromSmiles(my_smiles_string)
print(rdMolDescriptors.CalcMolFormula(my_mol))
This shows the result C8H11NO3
. You could parse that further to get only the number of hydrogens, if you need to do so. Alternately:
my_mol_with_explicit_h = Chem.AddHs(my_mol)
print(my_mol_with_explicit_h.GetNumAtoms() - my_mol_with_explicit_h.GetNumHeavyAtoms())
displays 11
. Slightly more cumbersome but it has the output you want. If you take the latter approach you don't even need to import rdMolDescriptors
.
Information on the system can be found here: https://en.wikipedia.org/wiki/Simplified_molecular-input_line-entry_system http://www.daylight.com/dayhtml/doc/theory/theory.smiles.html
The correct number of hydrogen atoms to fulfill the bond count around the other elements is assumed unless placed in square brackets. The bonds can be read from left to right and assumed to be a chain, unless placed in braces which represent a branch.
So there would be 1H around the first C (going from left to right) this is because it is c1 indicating it's one half of a ring closure so will have an extra bond attached, there is one H on the second C. The third C has a branch and an O (the chain continues after the braces close) which would have a single H attached, the third carbon has no H as the branch is attached via a double bond. (so far we have 3H)
The first C in the branch has no H and attaches to another branch and another O with an H. The first C in the second branch has a single H. The second C in the second branch is important because it has 1 after it like the first C. This indicates that they should have a bond between them forming a ring closure. It continues down the branch which now looks like a substituent on the ring. So it has no H. The third carbon in this branch has an O (with an H) and a new branch, so it has a single H. (So we have 7H so far) The third (and final 'branch' has a C attached to a N and two H, the N has two H attached. which adds 4H making 11H.
You have to convert the SMILES to a graph model. Most everything you want to do with SMILES requires you construct the graph model, i.e., nodes (atoms) and arcs (bonds). Once you have that, you can go through all nodes, and see how many of their sites are occupied by explicit bonds, the rest you hydrogenize.
If you do chemical informatics, you really need to learn these principles and learn to program them yourself.
But taking this obvious solution aside for a moment, with SMILES the question is always: can you simplify the solution so as to work purely text string based? Might you be able to use regular expression replace pattern matching to come up with your solution? And the answer is categorically no! Because regex patterns do not work for nested parenthesis as you use in SMILES to write out branches.
Could you use a parser to do it? May be. But if you go through this effort, you might just as well reconstruct your nodes and arc model, which then you can use to do so much more than to just hydrogenize.