OERMSD

Array-Based OERMSD

double OERMSD(const float *refcrds, const float *fitcrds, unsigned int size,
              bool overlay=false, double *rot=0, double *trans=0)

double OERMSD(const double *refcrds, const double *fitcrds, unsigned int size,
              bool overlay=false, double *rot=0, double *trans=0)

Returns the root mean squared deviation (i.e. RMSD) between two sets of Cartesian coordinates.

refcrds, fitcrds
These arrays should be of length size *3, and should contain the Cartesian coordinates of the two objects being assessed.
overlay
This flag indicates whether the RMSD of the two arrays in their current position is desired (false), or whether the lowest possible RMSD for the two arrays should be returned (true).
rot, trans
If an overlay calculation is carried out, the functions can report the rotation and translation required to achieve the minimum RMSD. An array of length double[9] should be passed to the ‘rot’ argument and an array of length double[3] should be passed as the ‘trans’ argument.

Example:

void OERMSD_Array(const double* refcrds, const double* fitcrds, unsigned int size)
{
  double rmsd1 = OERMSD(refcrds, fitcrds, size);
  
  bool overlay = false;
  double rmsd2 = OERMSD(refcrds, fitcrds, size, overlay);

  double rotmat[9];
  double rmsd3 = OERMSD(refcrds, fitcrds, size, overlay, rotmat);

  double transvec[3];
  double rmsd4 = OERMSD(refcrds, fitcrds, size, overlay, rotmat, transvec);
  cout << "RMSD1: " << rmsd1 << endl;
  cout << "RMSD2: " << rmsd2 << endl;
  cout << "RMSD3: " << rmsd3 << endl;
  cout << "RMSD4: " << rmsd4 << endl;
}

Full Molecule-Based OERMSD

double OERMSD(const OEMolBase &ref, const OEMolBase &fit, bool automorph=true,
              bool heavyOnly=true, bool overlay=false, double *rot=0,
              double *trans=0)
bool OERMSD(const OEMolBase &ref, const OEMCMolBase &fit, double *rmsdArray,
            bool automorph=true, bool heavyOnly=true, bool overlay=false,
            double *rot=0, double *trans=0)

Calculates the root mean squared deviation (i.e. RMSD ) between two molecules.

ref, fit
This function is overloaded for comparisons of a single-conformer (OEMolBase) reference molecule with either a single-conformer (OEMolBase) or a multi-conformer (OEMCMolBases) fit molecule.
rmsdArray
For the OEMolBase vs OEMolBase comparison, the RMSD is the return value. For the OEMolBase vs OEMCMolBase case, the RMSDs are returned in the ‘rmsdArray’ array. The ‘rmsdArray’ passed to this function should be of length fit.GetMaxConfIdx().
automorph
This flag indicates whether automorphisms should be taken into account during the RMSD calculation. Automorphisms are the symmetry related transformations of a molecule which can result in anomalously high RMSDs if not properly treated. For instance, t-butyl-benzene has a three-fold automorphism around the t-butyl group and a two-fold automorphism around the benzene ring.
heavyOnly
This flag indicates whether only heavy atoms should be considered or hydrogen atoms should be also taken into account as well when assessing automorphisms.

Hint

It is strongly recommended that one should consider carefully before setting the ‘automorph’ flag to true and the ‘heavyOnly’ flag to false due to the increased computational cost.

overlay
This flag indicates whether the RMSD of the molecules in their current position is desired (false), or whether the lowest possible RMSD for the two molecules should be returned (true).
rot, trans

If an overlay calculation is carried out, the functions can report the rotation and translation required to give this minimum RMSD.

In case when the fit molecule is single-conformer (OEMolBase), array of length double[9] should be passed to the ‘rot’ argument and an array of length double[3] should be passed as the ‘trans’ argument.

In case when the fit molecule is multi-conformer (OEMCMolBase), the array size of both rot and trans has to be multiplied by the length of fit.GetMaxConfIdx().

Hint

The arrays ‘rot’ and ‘trans’ described above can subsequently be applied to the ‘fit’ molecule using the OERotate and OETranslate functions if desired. It is important that OERotate and OETranslate are applied in that order.

Example:

void OERMSD_Full_MolBase(const OEMolBase& ref, const OEMolBase& fit)
{
  double rmsd1 = OERMSD(ref, fit);
  
  bool automorf = true;
  double rmsd2 = OERMSD(ref, fit, automorf);

  bool heavyOnly = true;
  double rmsd3 = OERMSD(ref, fit, automorf, heavyOnly);

  bool overlay = false;
  double rmsd4 = OERMSD(ref, fit, automorf, heavyOnly, overlay);

  double rotmat[9];
  double rmsd5 = OERMSD(ref, fit, automorf, heavyOnly, overlay, rotmat);

  double transvec[3];
  double rmsd6 = OERMSD(ref, fit, automorf, heavyOnly, overlay, rotmat, transvec);
  cout << "RMSD1: " << rmsd1 << endl;
  cout << "RMSD2: " << rmsd2 << endl;
  cout << "RMSD3: " << rmsd3 << endl;
  cout << "RMSD4: " << rmsd4 << endl;
  cout << "RMSD5: " << rmsd5 << endl;
  cout << "RMSD6: " << rmsd6 << endl;
}

void OERMSD_Full_MCMolBase(const OEMolBase& ref, const OEMCMolBase& fit)
{
  unsigned int nConfs = fit.GetMaxConfIdx();
  OEPlatform::OEMallocaPtr<double> vecRmsd = OEMalloca(nConfs * sizeof(double));
  OERMSD(ref, fit, vecRmsd);
  
  bool automorf = true;
  OERMSD(ref, fit, vecRmsd, automorf);

  bool heavyOnly = true;
  OERMSD(ref, fit, vecRmsd, automorf, heavyOnly);

  bool overlay = false;
  OERMSD(ref, fit, vecRmsd, automorf, heavyOnly, overlay);

  OEPlatform::OEMallocaPtr<double> rotmat = OEMalloca(9 * nConfs * sizeof(double));
  OERMSD(ref, fit, vecRmsd, automorf, heavyOnly, overlay, rotmat);

  OEPlatform::OEMallocaPtr<double> transvec = OEMalloca(3 * nConfs * sizeof(double));
  OERMSD(ref, fit, vecRmsd, automorf, heavyOnly, overlay, rotmat, transvec);
}

Partial Molecule-Based OERMSD

double OERMSD(const OEMolBase &ref, const OEMolBase &fit, const OEMatchBase &match,
              bool overlay=false, double *rot=0, double *trans=0)
bool OERMSD(const OEMolBase &ref, const OEMCMolBase &fit, double *rmsdArray,
            const OEMatchBase &match, bool overlay=false, double *rot=0,
            double *trans=0)

These functions are quite similar to the previous three. However, rather than considering automorphisms and heavy atoms, these functions allow a user to explicitly determine which substructure of the two molecules should be used to determine the RMSD.

ref, fit
This function is overloaded for comparisons of a single-conformer (OEMolBase) reference molecule with either a single-conformer (OEMolBase) or a multi-conformer (OEMCMolBases) fit molecule.
rmsdArray
For the OEMolBase vs OEMolBase comparison, the RMSD is the return value. For the OEMolBase vs OEMCMolBase case, the RMSDs are returned in the ‘rmsdArray’ array. The ‘rmsdArray’ passed to this function should be of length fit.GetMaxConfIdx().
match
The match determines the atoms of the fit* molecule that will be aligned to the atoms of the `ref molecule. The match can be generated by hand, or with any of OEChem TK‘s matching algorithms such as OESubSearch or OEMCSSearch.
overlay
This flag indicates whether the RMSD of the molecules in their current position is desired (false), or whether the lowest possible RMSD for the two molecules should be returned (true).
rot, trans

If an overlay calculation is carried out, the functions can report the rotation and translation required to give this minimum RMSD.

In case when the fit molecule is single-conformer (OEMolBase), array of length double[9] should be passed to the ‘rot’ argument and an array of length double[3] should be passed as the ‘trans’ argument.

In case when the fit molecule is multi-conformer (OEMCMolBase), the array size of both rot and trans has to be multiplied by the length of fit.GetMaxConfIdx().

Hint

The arrays ‘rot’ and ‘trans’ described above can subsequently be applied to the ‘fit’ molecule using the OERotate and OETranslate functions if desired. It is important that OERotate and OETranslate are applied in that order.

Example:

void OERMSD_Part_MolBase(const OEMolBase& ref, const OEMolBase& fit)
{
  OEMatch match;
  OESystem::OEIter<OEAtomBase> aRef = ref.GetAtoms(); 
  OESystem::OEIter<OEAtomBase> aFit = fit.GetAtoms();
  for (; aRef && aFit; ++aRef, ++aFit)
	match.AddPair(aRef, aFit);

  double rmsd1 = OERMSD(ref, fit, match);
  
  bool overlay = false;
  double rmsd2 = OERMSD(ref, fit, match, overlay);

  double rotmat[9];
  double rmsd3 = OERMSD(ref, fit, match, overlay, rotmat);

  double transvec[3];
  double rmsd4 = OERMSD(ref, fit, match, overlay, rotmat, transvec);
  cout << "RMSD1: " << rmsd1 << endl;
  cout << "RMSD2: " << rmsd2 << endl;
  cout << "RMSD3: " << rmsd3 << endl;
  cout << "RMSD4: " << rmsd4 << endl;
}

void OERMSD_Part_MCMolBase(const OEMolBase& ref, const OEMCMolBase& fit)
{
  OEMatch match;
  OESystem::OEIter<OEAtomBase> aRef = ref.GetAtoms(); 
  OESystem::OEIter<OEAtomBase> aFit = fit.GetAtoms();
  for (; aRef && aFit; ++aRef, ++aFit)
	  match.AddPair(aRef, aFit);

  unsigned int nConfs = fit.GetMaxConfIdx();
  OEPlatform::OEMallocaPtr<double> vecRmsd = OEMalloca(nConfs * sizeof(double));
  OERMSD(ref, fit, vecRmsd, match);

  bool overlay = false;
  OERMSD(ref, fit, vecRmsd, match, overlay);

  OEPlatform::OEMallocaPtr<double> rotmat = OEMalloca(9 * nConfs * sizeof(double));
  OERMSD(ref, fit, vecRmsd, match, overlay, rotmat);

  OEPlatform::OEMallocaPtr<double> transvec = OEMalloca(3 * nConfs * sizeof(double));
  OERMSD(ref, fit, vecRmsd, match, overlay, rotmat, transvec);
}

See also