3.7 Flavored Reading and Writing of Molecules

The general goal of the oemolstream input and output classes in OEChem is to provide the user with transparent access to the very complex task of reading and writing molecules in a wide variety of formats. However, occasionally, a programmer may want to tweak the behavior of specific writers without abandoning the oemolstreams to use the low level writers (such as OEWriteMDLFile). For these instances, oemolstreams provide the SetFlavor and GetFlavor methods.

The SetFlavor function takes two unsigned int arguments, the first is the format for which the flavor is being specified and the second is the flavor itself. The formats are specified as discussed above for SetFormat. The input flavors are specified in the OEChem namespace OEIFlavor and the output flavors are specified int the OEChem namespace OEOFlavor. Unlike the formats, the flavors are a bitmask and may be or'ed together. Under the OEIFlavor and OEOFlavor namespaces, there is a namespace for each format as well as a generic namespace. The generic namespace is used to control aromaticity perception and other properties common to all of formats. To completely specify a flavor, one would typically binary-OR a generic flag and a format specific flag and pass the resultant value to SetFlavor.

The default behavior for the PDB reader is that TER specifies the termination of a disconnected fragment within the same molecule while END specified the termination of a connection table (see the API manual for details). However, some users may want to have the reader split PDB input files into different molecules every time a TER appears.

The following code is an example of changing the PDB reader flavor.

#include "oechem.h"
#include <iostream>

using namespace OEChem;
using namespace OESystem;
using namespace std;

int main()
{
  OEMol mol;
  oemolistream ims("input.pdb");
  oemolostream oms("output.mol2");

  unsigned int flavor = OEIFlavor::Generic::Default |
                        (OEIFlavor::PDB::Default | OEIFlavor::PDB::TER);

  ims.SetFlavor(OEFormat::PDB,flavor);

  if (ims)
  {
    if (oms)
    {
      while (OEReadMolecule(ims,mol))
        OEWriteMolecule(oms,mol);
    }
    else cerr << "Error: Unable to write output.mol2" << endl;
  }
  else cerr << "Error: Unable to read input.pdb" << endl;
  return 0;
}

Similar low-level control can be exerted over both input and output stream readers using the powerful SetFlavor command. See the API documentation of each low-level reader for details on the effects of specific flavor flags.