/* (C) 2022 Cadence Design Systems, Inc. (Cadence) All rights reserved. TERMS FOR USE OF SAMPLE CODE The software below ("Sample Code") is provided to current licensees or subscribers of Cadence products or SaaS offerings (each a "Customer"). Customer is hereby permitted to use, copy, and modify the Sample Code, subject to these terms. Cadence claims no rights to Customer's modifications. Modification of Sample Code is at Customer's sole and exclusive risk. Sample Code may require Customer to have a then current license or subscription to the applicable Cadence offering. THE SAMPLE CODE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED. OPENEYE DISCLAIMS ALL WARRANTIES, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. In no event shall Cadence be liable for any damages or liability in connection with the Sample Code or its use. */ /**************************************************************************** * Performing RMSD calculation between a 3D reference molecule and * multi-conformer molecules ****************************************************************************/ using OpenEye.OEChem; using System; public class RMSD { private static void RMSDUtility(OEInterface itf) { if (!itf.GetBool("-verbose")) { OEChem.OEThrow.SetLevel(OEErrorLevel.Warning); } string rfname = itf.GetString("-ref"); string ifname = itf.GetString("-in"); bool automorph = itf.GetBool("-automorph"); bool heavy = itf.GetBool("-heavyonly"); bool overlay = itf.GetBool("-overlay"); oemolistream refifs = new oemolistream(); if (!refifs.open(rfname)) { OEChem.OEThrow.Fatal("Unable to open " + rfname + " for reading"); } OEGraphMol rmol = new OEGraphMol(); if (!OEChem.OEReadMolecule(refifs, rmol)) { OEChem.OEThrow.Fatal("Unable to read reference molecule"); } refifs.close(); oemolistream ifs = new oemolistream(); if (!ifs.open(ifname)) { OEChem.OEThrow.Fatal("Unable to open " + ifname + " for reading"); } oemolostream ofs = null; if (itf.HasString("-out")) { string ofname = itf.GetString("-out"); ofs = new oemolostream(); if (!ofs.open(ofname)) OEChem.OEThrow.Fatal("Unable to open " + ofname + " for writing"); if (!overlay) OEChem.OEThrow.Warning("Output is the same as input when overlay is false"); } foreach (OEMCMolBase mol in ifs.GetMCMolBases()) { OEChem.OEThrow.Info(mol.GetTitle()); uint maxIdx = mol.GetMaxConfIdx(); double[] rmsds = new double[maxIdx]; double[] rmtx = new double[9 * maxIdx]; double[] tmtx = new double[3 * maxIdx]; // performing RMSD for all conformers OEChem.OERMSD(rmol, mol, rmsds, automorph, heavy, overlay, rmtx, tmtx); foreach (OEConfBase conf in mol.GetConfs()) { uint cidx = conf.GetIdx(); OEChem.OEThrow.Info("Conformer " + cidx + ": rmsd = " + rmsds[cidx]); if (overlay) { OEChem.OERotate(conf, RMSD.slice(rmtx, cidx * 9, cidx * 9 + 9)); OEChem.OETranslate(conf, RMSD.slice(tmtx, cidx * 3, cidx * 3 + 3)); } } if (ofs != null) { OEChem.OEWriteMolecule(ofs, mol); } } if (ofs != null) { ofs.close(); } } private static double[] slice(double[] src, uint begin, uint end) { double[] ret = new double[end - begin]; uint cnt = 0; for (uint i = begin; i != end; i++, cnt++) { ret[cnt] = src[i]; } return ret; } public static void Main(String[] args) { OEInterface itf = new OEInterface(); OEChem.OEConfigure(itf, InterfaceData); if (OEChem.OEParseCommandLine(itf, args, "RMSD")) RMSDUtility(itf); } private static String InterfaceData = @" !BRIEF [options] [-ref ] [-in ] [-out ] !CATEGORY ""input/output options"" !PARAMETER -ref !TYPE string !REQUIRED true !BRIEF input reference mol file name !KEYLESS 1 !END !PARAMETER -in !ALIAS -i !TYPE string !REQUIRED true !BRIEF input mol file name !KEYLESS 2 !END !PARAMETER -out !ALIAS -o !TYPE string !REQUIRED false !BRIEF output file name, this implies that -overlay should be true !KEYLESS 3 !END !END !CATEGORY ""options"" !PARAMETER -automorph !TYPE bool !DEFAULT true !BRIEF assign best atom association !DETAIL If false, atoms are associated by order. If true, graph isomorphism is determined with symmetry perception. !END !PARAMETER -overlay !TYPE bool !DEFAULT true !BRIEF Minimize to the smallest RMSD !END !PARAMETER -heavyonly !TYPE bool !DEFAULT true !BRIEF Ignore hydrogens for RMSD calculation !END !PARAMETER -verbose !ALIAS -v !TYPE bool !DEFAULT false !BRIEF verbose !END !END "; }