18.1 Getting and Setting Coordinates of Atoms and Molecules

All molecules that conform to the OEMolBase API have a set of methods for getting coordinates and setting coordinates. In Python, there are several versions of each, used depending on the level of access desired and the performance required.

Member functions for getting coordinates:

Member functions for setting coordinates:

The first two methods in each section use Python data structures for output and input. This has a potential performance cost as the structures are created and populated in the Get methods and the converted to C data structures in the Set methods. However, for many applications, the cost is small and more than offset by the gain in using native data structures.

Here is a simple example, looping over the atoms in a molecule and printing each atom's coordinates:

ifs = oemolistream('drugs.sdf')
mol = OEGraphMol()
OEReadMolecule(ifs, mol)

for atom in mol.GetAtoms():
    print atom.GetIdx(), mol.GetCoords(atom)

If we want to format the output a bit better, we can send the tuple returned from GetCoords directly to a string interpolation operator:

ifs = oemolistream('drugs.sdf')
mol = OEGraphMol()
OEReadMolecule(ifs, mol)

for atom in mol.GetAtoms():
    print atom.GetIdx(),
    print 'x = %6.3f  y = %6.3f  z = %6.3f' % mol.GetCoords(atom)

To get the coordinates of the entire molecule in one call, we can use the following example. Note that the return from GetCoords() is a dictionary of triples indexed by atom index as returned from atom.GetIdx().

ifs = oemolistream('drugs.sdf')
mol = OEGraphMol()
OEReadMolecule(ifs, mol)

coords = mol.GetCoords()

for atom in mol.GetAtoms():
    print atom.GetIdx(),
    print 'x = %6.3f  y = %6.3f  z = %6.3f' % coords[atom.GetIdx()]

Setting of coordinates can be done in a completely analogous way using the corresponding SetCoords methods. To zero all the coordinates, on an atom-by-atom basis:

ifs = oemolistream('drugs.sdf')
mol = OEGraphMol()
OEReadMolecule(ifs, mol)

for atom in mol.GetAtoms():
    print 'x = %6.3f  y = %6.3f  z = %6.3f' % mol.GetCoords(atom)
    mol.SetCoords(atom, (0.0,0.0,0.0))
    print 'x = %6.3f  y = %6.3f  z = %6.3f' % mol.GetCoords(atom)

or you can set them all at once with a dictionary.

ifs = oemolistream('drugs.sdf')
mol = OEGraphMol()
OEReadMolecule(ifs, mol)

# create an empty dictionary
coords = {}

# loop over atoms, adding entry to dictionary
for atom in mol.GetAtoms():
    i = atom.GetIdx()
    coords[i] = (0.0, 0.0, 0.0)

# set coords
mol.SetCoords(coords)

# loop again to verify it worked
for atom in mol.GetAtoms():
    print mol.GetCoords(atom)


Subsections