Molecule Fragmentation

The OEMedChem TK currently provides four ways to partition a molecule into fragments:

These functions return an iterator over OEAtomBondSet objects that store the atoms and the bonds of the fragments.

The following examples (Listing 1, Listing 2) show how to fragment a molecule into ring and chain components. The code loops over the OEAtomBondSet objects returned by the OEGetRingChainFragments. Each OEAtomBondSet object is used to initialize an atom and a bond predicates. These predicates specify which atoms and bonds have to be considered when creating a subset of the molecule, i.e the fragment, when calling the OESubsetMol function. See the depiction of the input molecule and the generated fragments in Figure: Example of fragmentation.

Listing 1: Example of molecule fragmentation

#include <openeye.h>

#include <oesystem.h>
#include <oechem.h>
#include <oemedchem.h>

using namespace OESystem;
using namespace OEChem;
using namespace OEMedChem;

int main()
{
  OEGraphMol mol;
  OESmilesToMol(mol, "COc1ccc(cc1)CC(=O)N");

  for (OEIter<OEAtomBondSet> fi = OEGetRingChainFragments(mol); fi; ++fi)
  {
    OEIsMemberPtr<OEAtomBase> fragatompred(fi->GetAtoms());
    OEIsMemberPtr<OEBondBase> fragbondpred(fi->GetBonds());

    OEGraphMol fragment;
    bool adjustHCount = true;
    OESubsetMol(fragment, mol, fragatompred, fragbondpred, adjustHCount);
    std::cout << OEMolToSmiles(fragment) << std::endl;
  }
  return 0;
}

The output of Listing 1 is the following:

CO
c1ccccc1
CC(=O)N
../_images/Fragmentation.png

Example of fragmentation (A) input molecule (B) fragments returned by the OEGetRingChainFragments function

See also

The following example (Listing 2) shows how to fragment a molecule into ring and chain components with annotations. See the depiction of the input molecule and the generated fragments in Figure: Example of Bemis Murcko fragmentation.

Listing 2: Example of molecule fragmentation with annotations

#include <openeye.h>

#include <oesystem.h>
#include <oechem.h>
#include <oemedchem.h>

using namespace OESystem;
using namespace OEChem;
using namespace OEMedChem;

int main()
{
  OEGraphMol mol;
  OESmilesToMol(mol, "CCOc1ccc(cc1)CC(OC)c2ccccc2CC(=O)N");

  for (OEIter<OEAtomBondSet> absets = OEGetBemisMurcko(mol); absets; ++absets)
  {
    OEAtomBondSet &abset = absets;
    OEIsMemberPtr<OEAtomBase> fragatompred(abset.GetAtoms());
    OEIsMemberPtr<OEBondBase> fragbondpred(abset.GetBonds());

    OEGraphMol fragment;
    bool adjustHCount = true;
    OESubsetMol(fragment, mol, fragatompred, fragbondpred, adjustHCount);
    for (OEIter<const OERole> role = abset.GetRoles(); role; ++role)
      std::cout << role->GetName() << OEMolToSmiles(fragment) << std::endl;
  }
  return 0;
}

The output of Listing 2 is the following:

Framework c1ccc(cc1)CCc2ccccc2
Ring c1ccccc1.c1ccccc1
Linker CC
Sidechain CCO.CC(=O)N.CO
../_images/OEGetBemisMurcko.png

Example of Bemis Murcko fragmentation

The following example (Listing 3) shows how to fragment a molecule and include unsaturated hetero bonds on the main framework. See the depiction of the input molecule and the generated fragments in Figure: Example of custom Bemis Murcko fragmentation including heteroatoms.

Listing 3: Example of custom molecule fragmentation

#include <openeye.h>

#include <oesystem.h>
#include <oechem.h>
#include <oemedchem.h>

using namespace OESystem;
using namespace OEChem;
using namespace OEMedChem;

int main()
{
  OEGraphMol mol;
  const char* exampleSmiles = "CCc1nc(nc(n1)OC)NC(=O)NS(=O)(=O)c2ccccc2OC";
  OESmilesToMol(mol, exampleSmiles); 
  OEBemisMurckoOptions options;
  options.SetUnsaturatedHeteroBonds(true);

  for (OEIter<OEAtomBondSet> absets = OEGetBemisMurcko(mol, options); absets; ++absets)
  {
    OEAtomBondSet &abset = absets;
    OEIsMemberPtr<OEAtomBase> fragatompred(abset.GetAtoms());
    OEIsMemberPtr<OEBondBase> fragbondpred(abset.GetBonds());

    OEGraphMol fragment;
    bool adjustHCount = true;
    OESubsetMol(fragment, mol, fragatompred, fragbondpred, adjustHCount);
    for (OEIter<const OERole> role = abset.GetRoles(); role; ++role)
      std::cout << role->GetName() << OEMolToSmiles(fragment) << std::endl;
  }
  return 0;
}

The output of Listing 3 is the following:

Framework c1ccc(cc1)S(=O)(=O)NC(=O)Nc2ncncn2
Ring c1ccccc1.c1ncncn1
Linker C(=O)(N)NS(=O)=O
Sidechain CC.CO.CO
../_images/OEGetBemisMurckoUnsatHetero.png

Example of Bemis Murcko fragmentation including unsaturated hetero bonds on main framework.

The following example (Listing 4) shows how to fragment a molecule and include custom sidechains on the main framework. See the depiction of the input molecule and the generated fragments in Figure: Example of custom Bemis Murcko fragmentation including custom substituents.

Listing 4: Example of custom molecule fragmentation

#include <openeye.h>

#include <oesystem.h>
#include <oechem.h>
#include <oemedchem.h>

using namespace OESystem;
using namespace OEChem;
using namespace OEMedChem;

int main()
{
  OEGraphMol mol;
  const char* exampleSmiles = "CCc1nc(nc(n1)OC)NC(CC(=O)N)NS(=O)(=O)c2ccccc2CC(=O)N";
  OESmilesToMol(mol, exampleSmiles); 
  
  OESubSearch ss;
  ss.Init("[#6]-CC(=O)N");
  OEBemisMurckoOptions options;
  options.SetSubstituentSearch(ss);
  
  for (OEIter<OEAtomBondSet> absets = OEGetBemisMurcko(mol, options); absets; ++absets)
  {
    OEAtomBondSet &abset = absets;
    OEIsMemberPtr<OEAtomBase> fragatompred(abset.GetAtoms());
    OEIsMemberPtr<OEBondBase> fragbondpred(abset.GetBonds());

    OEGraphMol fragment;
    bool adjustHCount = true;
    OESubsetMol(fragment, mol, fragatompred, fragbondpred, adjustHCount);
    for (OEIter<const OERole> role = abset.GetRoles(); role; ++role)
      std::cout << role->GetName() << OEMolToSmiles(fragment) << std::endl;
  }
  return 0;
}

The output of Listing 4 is the following:

Framework c1ccc(c(c1)CC(=O)N)[SH4]NC(CC(=O)N)Nc2ncncn2
Ring c1ccc(cc1)CC(=O)N.c1ncncn1
Linker C(C(N)N[SH5])C(=O)N
Sidechain CC.CO.O.O
../_images/OEGetBemisMurckoCustomSubsearch.png

Example of Bemis Murcko fragmentation including custom substituents on framework