19.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.

Member functions for getting coordinates: 

bool GetCoords(float *) const
bool GetCoords(double *) const
bool GetCoords(const OEAtomBase *, float *) const
bool GetCoords(const OEAtomBase *, double *) const

Member functions for setting coordinates: 

bool SetCoords(const float *)
bool SetCoords(const double *)
bool SetCoords(const OEAtomBase *, const float *)
bool SetCoords(const OEAtomBase *, const double *)

The first two methods in each section are for getting or setting all the coordinates of the molecule at one time, while the second pair can be used on an atom-by-atom basis. Here is a simple example, looping over the atoms in a molecule and printing each atom's coordinates:

oemolistream ifs("drugs.sdf");
OEGraphMol mol;
OEReadMolecule(ifs, mol);

float xyz[3];
for (OEIter<OEAtomBase> atom=mol.GetAtoms();atom;++atom)
{
  mol.GetCoords(atom, xyz);
  printf("idx: %d  x=%f y=%f z=%f\n", atom->GetIdx(),
         xyz[0], xyz[1], xyz[2]);
}

To get the coordinates of the entire molecule in one call, we can use the following example. Note that to properly deal with potentially deleted atoms, arrays for atom properties should always be sized using mol.GetMaxAtomIdx() NOT mol.NumAtoms(). 

oemolistream ifs("drugs.sdf");
OEGraphMol mol;
OEReadMolecule(ifs, mol);

float coords[3*mol.GetMaxAtomIdx()];
mol.GetCoords(coords);
for (OEIter<OEAtomBase> atom=mol.GetAtoms();atom;++atom)
{
  unsigned int idx=atom->GetIdx();
  printf("idx: %d  x=%f y=%f z=%f\n",idx,coords[3*idx],
         coords[3*idx+1], coords[3*idx+2]);
}

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:

oemolistream ifs("drugs.sdf");
OEGraphMol mol;
OEReadMolecule(ifs, mol);

float xyz[3];
float zero={0.0f, 0.0f, 0.0f};
for (OEIter<OEAtomBase> atom=mol.GetAtoms();atom;++atom)
{
  mol.SetCoords(atom, zero);
  mol.GetCoords(atom, xyz);
  printf("idx: %d  x=%f y=%f z=%f\n", atom->GetIdx(),
         xyz[0], xyz[1], xyz[2]);
}

or you can set them all at once.

oemolistream ifs("drugs.sdf");
OEGraphMol mol;
OEReadMolecule(ifs, mol);
float zeroes[3*mol.GetMaxAtomIdx()];
memset(zeroes, 0, 3*mol.GetMaxAtomIdx()*sizeof(float));
mol.SetCoords(zeroes);