OEChem has the ability to store and retrieve stereochemical information for atoms and bonds independent of two or three dimensional coordinates. The current version of OEChem supports stereochemistry definitions of handedness around tetrahedral centers, and cis/trans configuration around bonds.
The following two code snippets demonstrate how to loop over chiral atoms using the OEIsChiralAtom functor and the IsChiral method of the OEAtomBase class.
for atom in mol.GetAtoms(OEIsChiralAtom()):
print atom.GetIdx(),OEGetAtomicSymbol(atom.GetAtomicNum())
for atom in mol.GetAtoms():
if atom.IsChiral():
print atom.GetIdx(),OEGetAtomicSymbol(atom.GetAtomicNum())
The user can also set the atom chirality manually using the OEAtomBase.SetChiral method.
Warning
When a molecule is imported from a file, its atom and bond chirality are not automatically perceived, the user has to call OEPerceiveChiral explicitly.
The definition handedness in OEChem is demonstrated pictorially in the following table:
| R-configuration | S-configuration |
|---|---|
![]() |
![]() |
| [C@@H](Cl)(Br)N | [C@H](Cl)(Br)N |
![]() |
![]() |
| OEAtomStereo_RightHanded (clockwise) | OEAtomStereo_LeftHanded (counter-clockwise) |
Looking down the bond between atom number one (hydrogen) and the central atom (carbon), handedness is defined as the direction of travel from atom number two (chlorine) to atom number three (bromine). The direction of travel must always be along the acute angle formed by atom two (chlorine), the central atom (carbon), and atom three (bromine). Right handed and left handed directions of travel can also be though of as clockwise and counterclockwise, respectively.
Note
The definition of handedness for tetrahedral stereochemistry does not imply chirality around a tetrahedral center, but rather indicates relative positions of neighboring atoms.
Note that the method OEAtomBase.GetStereo requires a vector containing pointers to the neighboring atoms as the first argument. The handedness value returned from OEAtomBase.GetStereo will depend on the order of the neighboring atoms as they appear in the passed vector.
The first neighbor atom in the vector passed to OEAtomBase.GetStereo is taken as atom number one for the determination of handedness. Likewise, subsequent atoms in the neighbor atom vector are assigned sequentially to positions in the handedness definition. Although, three neighboring atoms are sufficient to determine the handedness around a trigonal pyramidal or tetrahedral center, either three or four atoms can be provided to the OEAtomBase.GetStereo function when requesting a value for tetrahedral chirality. The following table shows the return values of OEAtomBase.GetStereo method by passing the neighbor atoms in different order.
| neighbor order | [C@@H](Cl)(Br)N | [C@H](Cl)(Br)N |
|---|---|---|
| H Cl Br N | right handed | left handed |
| H Cl Br | right handed | left handed |
| H Br Cl N | left handed | right handed |
| H Br Cl | left handed | right handed |
| H Cl N Br | left handed | right handed |
| H Cl N | left handed | right handed |
| Cl Br H | right handed | left handed |
| Cl H N | right handed | left handed |
| Cl N Br | right handed | left handed |
The OEAtomBase.HasStereoSpecified method returns a boolean value which indicates whether stereochemical information of a particular type as been stored for an atom. The unsigned integer type argument must be a constant listed in the OEAtomStereo namespace. If an atom has associated stereochemical data, it can be retrieved using OEAtomBase.GetStereo method. Multiple possible values may be associated with each class of stereochemistry. For instance, if an atom has associated tetrahedral stereochemistry, the possible values are OEAtomStereo_Undefined, OEAtomStereo_RightHanded (or just OEAtomStereo_Right), or OEAtomStereo_LeftHanded (or just OEAtomStereo_Left ). The following code sample demonstrates looping over atoms, testing for atoms which have tetrahedral stereochemistry, and printing out the value of the tetrahedral stereochemistry. (See also the input structure depicted in Figure: Atom stereo.
Listing 1: Accessing atom stereo information
#!/usr/bin/env python
from openeye.oechem import *
mol = OEGraphMol()
OEParseSmiles(mol,"[H][C@]1(NC[C@@H](CC1CO[C@H]2CC[C@@H](CC2)O)N)[H]")
OEPerceiveChiral(mol)
for atom in mol.GetAtoms():
chiral = atom.IsChiral()
stereo = OEAtomStereo_Undefined
if atom.HasStereoSpecified(OEAtomStereo_Tetrahedral):
v = []
for nbr in atom.GetAtoms():
v.append(nbr)
stereo = atom.GetStereo(v,OEAtomStereo_Tetrahedral)
if chiral or stereo != OEAtomStereo_Undefined:
print "Atom:",atom.GetIdx(), "chiral=",chiral,"stereo=",
if stereo == OEAtomStereo_RightHanded:
print "right handed"
elif stereo == OEAtomStereo_LeftHanded:
print "left handed"
else:
print "undefined"
The output of the preceding program is the following:
Atom: 1 chiral= False stereo= left handed
Atom: 4 chiral= True stereo= right handed
Atom: 7 chiral= True stereo= undefined
Atom: 10 chiral= False stereo= left handed
Atom: 14 chiral= False stereo= right handed
Atom stereo
As mentioned before, tetrahedral stereochemistry (i.e. specified atom stereo) does not imply chirality around a tetrahedral center. For example atoms 1, 10 and 14 in Figure: Atom stereo have specified atom stereo, even though they are non-chiral. Vice versa, atom can be chiral but with unspecified atom stereo configuration (such as atom 7 in Figure: Atom stereo ). Atoms 1 and 6 are non-chiral but they have atom stereo information and they are relative to each other.
The following example shows how to manually set the atom stereo of atom 7 (chiral, undefined) to left by the OEAtomBase.SetStereo method.
Listing 2: Setting atom stereo information
#!/usr/bin/env python
from openeye.oechem import *
mol = OEGraphMol()
OEParseSmiles(mol,"[H][C@]1(NC[C@@H](CC1CO[C@H]2CC[C@@H](CC2)O)N)[H]")
OEPerceiveChiral(mol)
for atom in mol.GetAtoms():
chiral = atom.IsChiral()
stereo = OEAtomStereo_Undefined
if atom.IsChiral() and not atom.HasStereoSpecified(OEAtomStereo_Tetrahedral):
v = []
for neigh in atom.GetAtoms():
v.append(neigh)
atom.SetStereo(v,OEAtomStereo_Tetra,OEAtomStereo_Left)
print OECreateIsoSmiString(mol)
The output of the preceding program is the following:
[H][C@@]1([C@@H](C[C@H](CN1)N)CO[C@H]2CC[C@@H](CC2)O)[H]
Just as in OEAtomBase.GetStereo, the vector of neighbor atoms provide the references about which the handedness is defined. The first of the integer arguments is the stereochemistry type (i.e. OEAtomStereo_Tetrahedral (or just OEAtomStereo_Tetra) , and the second is the associated value (i.e. OEAtomStereo_Right or OEAtomStereo_Left).
Stereochemistry around bonds can be specified in a similar fashion to stereochemistry about atom centers. The request for stereochemistry of a particular class can be made of an OEBondBase using the method OEBondBase.HasStereoSpecified. The type argument provided to OEBondBase.HasStereoSpecified indicates the type of stereochemistry requested, and must be one of the constants listed in the OEBondStereo namespace. The most commonly requested stereochemistry value of bonds is whether the configuration of two atoms around a non-rotatable bond is cis or trans. The following code sample demonstrates a loop over bonds which tests for bonds with associated stereochemistry, and retrieval of whether the neighboring atoms are cis or trans relative to one another. (See also the input structure depicted in Figure: Bond stereo.
Listing 3: Accessing bond stereo information
#!/usr/bin/env python
from openeye.oechem import *
mol = OEGraphMol()
OEParseSmiles(mol, "C\\C=C\\C=C/C=CC")
for bond in mol.GetBonds():
if bond.HasStereoSpecified(OEBondStereo_CisTrans):
for atomB in bond.GetBgn().GetAtoms():
if atomB == bond.GetEnd():
continue
for atomE in bond.GetEnd().GetAtoms():
if atomE == bond.GetBgn():
continue
v = []
v.append(atomB)
v.append(atomE)
stereo = bond.GetStereo(v,OEBondStereo_CisTrans)
print "Atoms:",atomB.GetIdx(),"and",atomE.GetIdx(),"are",
if stereo == OEBondStereo_Cis:
print "cis"
elif stereo == OEBondStereo_Trans:
print "trans"
The output of the preceding program is the following:
Atoms: 0 and 3 are trans
Atoms: 2 and 5 are cis
Bond stereo
Note that even though the double bond defined by atoms 4–5–6–7 is depicted as trans (see Figure: Bond stereo) it is still considered undefined, since no stereo information is encoded for this bond in the input SMILES.
The following example shows how to manually set this missing bond stereo to trans by the OEBondBase.SetStereo method.
Listing 4: Setting bond stereo information
#!/usr/bin/env python
from openeye.oechem import *
mol = OEGraphMol()
OEParseSmiles(mol, "C\\C=C\\C=C/C=CC")
for bond in mol.GetBonds():
if bond.GetOrder() == 2 and not bond.HasStereoSpecified(OEBondStereo_CisTrans):
v = []
for neigh in bond.GetBgn().GetAtoms():
if neigh != bond.GetEnd():
v.append(neigh)
break
for neigh in bond.GetEnd().GetAtoms():
if neigh != bond.GetBgn():
v.append(neigh)
break
bond.SetStereo(v,OEBondStereo_CisTrans,OEBondStereo_Trans)
print OECreateIsoSmiString(mol)
The first integer argument of the method OEBondBase.SetStereo is used to specify the type of stereochemistry (i.e. OEBondStereo_CisTrans). The second integer argument specifies the bond stereo configuration (i.e. OEBondStereo_Cis or OEBondStereo_Trans)
The output of the preceding program is the following:
C/C=C/C=C\C=C\C