10.7 Using NewConf

The most common method to create conformers in a molecule is by reading a molecule from a file (see chapter "Reading and Writing Molecules"). However, when manipulating molecules it is often necessary to create conformers on-the-fly. In OEChem, this is done with the OEMCMolBase::NewConf function. There are five prominent overloads of NewConf. All of the overloads create conformers with the capacity to store coordinates for the current number of atoms in the molecule. NewAtom and NewBond adjust this capacity as necessary. The default OEMCMolBase constructor puts the molecule in a state with a single empty conformer (as does the OEMCMolBase::Clear function). The DeleteConfs function of the OEMCMolBase removes all of the conformers of the molecule.

#include "oechem.h"
#include "oesystem.h"

using namespace OEChem;
using namespace std;

int main()
{
  OEMol mol;

  cerr << "Default NumConfs = " << mol.NumConfs() << endl;

  mol.NewConf();

  cerr << "After One Additional, NumConfs = " << mol.NumConfs() << endl;

  mol.DeleteConfs();

  cerr << "After Deletion, NumConfs = " << mol.NumConfs() << endl;

  return 0;
}

The code above will produce the output:

1
2
0

The overloads of the NewConf function are:

NewConf()
NewConf(const float *coords)
NewConf(const OEMolBase *mol)
NewConf(const OEConfBase *conf)

After the NewConf with no arguments has been called, the coordinates of individual atoms can be set using the OEConfBase::SetCoords function which takes an atom, or all of the atoms can be set at once with the OEConfBase::SetCoords which takes only a float* or only a double*.

The NewConf overload which takes an argument float* is expecting an array of size 3*GetMaxAtomIdx()*sizeof(float) with the Cartesian coordinates of each OEAtomBase atom of the new conformer in coords[atom->GetIdx()*3].

The NewConf which takes a pointer to a OEMolBase is expecting the molecule passed in to have the same graph as the OEMCMolBase which is the parent of the new conformer. It is important to note that this version of NewConf can take an OEGraphMol, OEMol, or OEMCMol. In the latter two cases, the coordinates of the new conformer will come from the active conformation of the molecule passed.

Finally, there is an overload which takes a pointer to a conformer. This function behaves the same as the overload which takes an OEMolBase.

#include "oesystem.h"
#include "oechem.h"

using namespace OESystem;
using namespace OEChem;

void GetGoodMol(OEMCMolBase &destination,const OEMCMolBase &source)
{
  destination.DeleteConfs();
  OEConfBase *newConf;
  char buf[2048];

  OEIter<OEConfBase> conf;
  for(conf = source.GetConfs();conf;++conf)
  {
    if(conf->GetEnergy() < -15.5f)
    {
      newConf = destination.NewConf(conf);
      sprintf(buf,"Low Energy Conformer: energy = %.3f",newConf->GetEnergy());
      newConf->SetTitle(buf);
    }
  }
}

int main()
{
  OEMol mol;
  OEMol goodmol;

  oemolistream mis("input.oeb");
  oemolostream mos("output.sdf");

  while(OEReadMolecule(mis,mol))
  {
    GetGoodMol(goodmol,mol);
    OEWriteMolecule(mos,goodmol);
  }

  return 0;
}

The Example above demonstrates copying conformers from one OEMol to another using the NewConf and DeleteConfs functions. The main routine reads all of the molecules from the file "input.oeb" and writes the molecules with only their low-energy conformations to "output.sdf". The function GetGoodMol generates a destination molecule that contains only the low-energy conformations of the source molecule. The title of each new conformer is set to reflect its energy.