Package rdkit :: Package Chem :: Module EnumerateStereoisomers
[hide private]
[frames] | no frames]

Module EnumerateStereoisomers

source code

Classes [hide private]
  StereoEnumerationOptions
- tryEmbedding: if set the process attempts to generate a standard RDKit distance geometry conformation for the stereisomer.
  _BondFlipper
  _AtomFlipper
  _RangeBitsGenerator
  _UniqueRandomBitsGenerator
Functions [hide private]
 
_getFlippers(mol, options) source code
 
EnumerateStereoisomers(m, options=StereoEnumerationOptions(), verbose=False)
returns a generator that yields possible stereoisomers for a molecule
source code
Variables [hide private]
  __package__ = 'rdkit.Chem'

Imports: six, random, Chem, EmbedMolecule


Function Details [hide private]

EnumerateStereoisomers(m, options=StereoEnumerationOptions(), verbose=False)

source code 
returns a generator that yields possible stereoisomers for a molecule

Arguments:
  - m: the molecule to work with
  - verbose: toggles how verbose the output is

A small example with 3 chiral atoms and 1 chiral bond (16 theoretical stereoisomers):
>>> from rdkit import Chem
>>> from rdkit.Chem.EnumerateStereoisomers import EnumerateStereoisomers, StereoEnumerationOptions
>>> m = Chem.MolFromSmiles('BrC=CC1OC(C2)(F)C2(Cl)C1')
>>> isomers = tuple(EnumerateStereoisomers(m))
>>> len(isomers)
16
>>> for smi in sorted(Chem.MolToSmiles(x, isomericSmiles=True) for x in isomers):
...     print(smi)
...
F[C@@]12C[C@@]1(Cl)C[C@@H](/C=C/Br)O2
F[C@@]12C[C@@]1(Cl)C[C@@H](/C=C\Br)O2
F[C@@]12C[C@@]1(Cl)C[C@H](/C=C/Br)O2
F[C@@]12C[C@@]1(Cl)C[C@H](/C=C\Br)O2
F[C@@]12C[C@]1(Cl)C[C@@H](/C=C/Br)O2
F[C@@]12C[C@]1(Cl)C[C@@H](/C=C\Br)O2
F[C@@]12C[C@]1(Cl)C[C@H](/C=C/Br)O2
F[C@@]12C[C@]1(Cl)C[C@H](/C=C\Br)O2
F[C@]12C[C@@]1(Cl)C[C@@H](/C=C/Br)O2
F[C@]12C[C@@]1(Cl)C[C@@H](/C=C\Br)O2
F[C@]12C[C@@]1(Cl)C[C@H](/C=C/Br)O2
F[C@]12C[C@@]1(Cl)C[C@H](/C=C\Br)O2
F[C@]12C[C@]1(Cl)C[C@@H](/C=C/Br)O2
F[C@]12C[C@]1(Cl)C[C@@H](/C=C\Br)O2
F[C@]12C[C@]1(Cl)C[C@H](/C=C/Br)O2
F[C@]12C[C@]1(Cl)C[C@H](/C=C\Br)O2

Because the molecule is constrained, not all of those isomers can
actually exist. We can check that:
>>> opts = StereoEnumerationOptions(tryEmbedding=True)
>>> isomers = tuple(EnumerateStereoisomers(m, options=opts))
>>> len(isomers)
8
>>> for smi in sorted(Chem.MolToSmiles(x,isomericSmiles=True) for x in isomers):
...     print(smi)
...
F[C@@]12C[C@]1(Cl)C[C@@H](/C=C/Br)O2
F[C@@]12C[C@]1(Cl)C[C@@H](/C=C\Br)O2
F[C@@]12C[C@]1(Cl)C[C@H](/C=C/Br)O2
F[C@@]12C[C@]1(Cl)C[C@H](/C=C\Br)O2
F[C@]12C[C@@]1(Cl)C[C@@H](/C=C/Br)O2
F[C@]12C[C@@]1(Cl)C[C@@H](/C=C\Br)O2
F[C@]12C[C@@]1(Cl)C[C@H](/C=C/Br)O2
F[C@]12C[C@@]1(Cl)C[C@H](/C=C\Br)O2

By default the code only expands unspecified stereocenters:
>>> m = Chem.MolFromSmiles('BrC=C[C@H]1OC(C2)(F)C2(Cl)C1')
>>> isomers = tuple(EnumerateStereoisomers(m))
>>> len(isomers)
8
>>> for smi in sorted(Chem.MolToSmiles(x,isomericSmiles=True) for x in isomers):
...     print(smi)
...
F[C@@]12C[C@@]1(Cl)C[C@@H](/C=C/Br)O2
F[C@@]12C[C@@]1(Cl)C[C@@H](/C=C\Br)O2
F[C@@]12C[C@]1(Cl)C[C@@H](/C=C/Br)O2
F[C@@]12C[C@]1(Cl)C[C@@H](/C=C\Br)O2
F[C@]12C[C@@]1(Cl)C[C@@H](/C=C/Br)O2
F[C@]12C[C@@]1(Cl)C[C@@H](/C=C\Br)O2
F[C@]12C[C@]1(Cl)C[C@@H](/C=C/Br)O2
F[C@]12C[C@]1(Cl)C[C@@H](/C=C\Br)O2

But we can change that behavior:
>>> opts = StereoEnumerationOptions(onlyUnassigned=False)
>>> isomers = tuple(EnumerateStereoisomers(m, options=opts))
>>> len(isomers)
16

Since the result is a generator, we can allow exploring at least parts of very
large result sets:
>>> m = Chem.MolFromSmiles('Br' + '[CH](Cl)' * 20 + 'F')
>>> opts = StereoEnumerationOptions(maxIsomers=0)
>>> isomers = EnumerateStereoisomers(m, options=opts)
>>> for x in range(5):
...   print(Chem.MolToSmiles(next(isomers),isomericSmiles=True))
F[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)Br
F[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@H](Cl)Br
F[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@H](Cl)[C@@H](Cl)Br
F[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@H](Cl)[C@H](Cl)Br
F[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@H](Cl)[C@@H](Cl)[C@@H](Cl)Br

Or randomly sample a small subset:
>>> m = Chem.MolFromSmiles('Br' + '[CH](Cl)' * 20 + 'F')
>>> opts = StereoEnumerationOptions(maxIsomers=3)
>>> isomers = EnumerateStereoisomers(m, options=opts)
>>> for smi in sorted(Chem.MolToSmiles(x, isomericSmiles=True) for x in isomers):
...     print(smi)
F[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@H](Cl)[C@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@H](Cl)[C@@H](Cl)[C@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@H](Cl)[C@H](Cl)[C@H](Cl)[C@H](Cl)[C@H](Cl)[C@@H](Cl)Br
F[C@@H](Cl)[C@H](Cl)[C@@H](Cl)[C@H](Cl)[C@@H](Cl)[C@H](Cl)[C@H](Cl)[C@H](Cl)[C@H](Cl)[C@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@H](Cl)[C@@H](Cl)Br
F[C@H](Cl)[C@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@H](Cl)[C@H](Cl)[C@H](Cl)[C@H](Cl)[C@H](Cl)[C@@H](Cl)[C@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@@H](Cl)[C@H](Cl)[C@@H](Cl)Br