Added AtomComparator.AtomCompareAnyHeavyAtom and test cases to FMCS code (#2656)

* Added AtomComparator.AtomCompareAnyHeavyAtom and test cases to FMCS code

* Added AtomComparator.AtomCompareAnyHeavyAtom

* Added AtomComparator.AtomCompareAnyHeavyAtom - fixed test typo

* Added AtomComparator.AtomCompareAnyHeavyAtom and test cases to FMCS code (2)

* Added AtomComparator.AtomCompareAnyHeavyAtom - fixed test cases

* Added AtomComparator.AtomCompareAnyHeavyAtom and test cases

* Update Code/GraphMol/FMCS/FMCS.cpp

Co-Authored-By: Greg Landrum <greg.landrum@gmail.com>

* Reverted tabs to 4 spaces

* Update FMCS.cpp
This commit is contained in:
Steve Roughley
2019-10-03 16:19:22 +01:00
committed by Greg Landrum
parent b92c265348
commit 710bdfa60b
6 changed files with 125 additions and 2 deletions

View File

@@ -57,6 +57,8 @@ void parseMCSParametersJSON(const char* json, MCSParameters* params) {
p.AtomTyper = MCSAtomCompareElements;
else if (0 == strcmp("Isotopes", s.c_str()))
p.AtomTyper = MCSAtomCompareIsotopes;
else if (0 == strcmp("AnyHeavy", s.c_str()))
p.AtomTyper = MCSAtomCompareAnyHeavyAtom;
s = pt.get<std::string>("BondCompare", "def");
if (0 == strcmp("Any", s.c_str()))
@@ -109,6 +111,9 @@ MCSResult findMCS(const std::vector<ROMOL_SPTR>& mols, bool maximizeBonds,
case AtomCompareIsotopes:
ps->AtomTyper = MCSAtomCompareIsotopes;
break;
case AtomCompareAnyHeavyAtom:
ps->AtomTyper = MCSAtomCompareAnyHeavyAtom;
break;
}
ps->AtomCompareParameters.RingMatchesRingOnly = ringMatchesRingOnly;
switch (bondComp) {
@@ -221,6 +226,18 @@ bool MCSAtomCompareIsotopes(const MCSAtomCompareParameters& p,
return true;
}
bool MCSAtomCompareAnyHeavyAtom(const MCSAtomCompareParameters& p,
const ROMol& mol1, unsigned int atom1,
const ROMol& mol2, unsigned int atom2, void*) {
const Atom& a1 = *mol1.getAtomWithIdx(atom1);
const Atom& a2 = *mol2.getAtomWithIdx(atom2);
//Any atom, including H, matches another atom of the same type, according to the other flags
if (a1.getAtomicNum() == a2.getAtomicNum() || (a1.getAtomicNum() > 1 && a2.getAtomicNum() > 1)){
return MCSAtomCompareAny(p,mol1,atom1,mol2,atom2,nullptr);
}
return false;
}
//=== BOND COMPARE ========================================================
class BondMatchOrderMatrix {

View File

@@ -49,6 +49,10 @@ RDKIT_FMCS_EXPORT bool MCSAtomCompareAny(const MCSAtomCompareParameters& p,
const ROMol& mol1, unsigned int atom1,
const ROMol& mol2, unsigned int atom2,
void* userData);
RDKIT_FMCS_EXPORT bool MCSAtomCompareAnyHeavyAtom(const MCSAtomCompareParameters& p,
const ROMol& mol1, unsigned int atom1,
const ROMol& mol2, unsigned int atom2,
void* userData);
RDKIT_FMCS_EXPORT bool MCSAtomCompareElements(
const MCSAtomCompareParameters& p, const ROMol& mol1, unsigned int atom1,
@@ -125,7 +129,8 @@ RDKIT_FMCS_EXPORT MCSResult findMCS_P(const std::vector<ROMOL_SPTR>& mols,
typedef enum {
AtomCompareAny,
AtomCompareElements,
AtomCompareIsotopes
AtomCompareIsotopes,
AtomCompareAnyHeavyAtom
} AtomComparator;
typedef enum {
BondCompareAny,

View File

@@ -27,6 +27,9 @@ void SetMCSAtomTyper(MCSParameters &p, AtomComparator atomComp) {
case AtomCompareIsotopes:
p.AtomTyper = MCSAtomCompareIsotopes;
break;
case AtomCompareAnyHeavyAtom:
p.AtomTyper = MCSAtomCompareAnyHeavyAtom;
break;
}
}
void SetMCSBondTyper(MCSParameters &p, BondComparator bondComp) {
@@ -120,7 +123,8 @@ BOOST_PYTHON_MODULE(rdFMCS) {
python::enum_<RDKit::AtomComparator>("AtomCompare")
.value("CompareAny", RDKit::AtomCompareAny)
.value("CompareElements", RDKit::AtomCompareElements)
.value("CompareIsotopes", RDKit::AtomCompareIsotopes);
.value("CompareIsotopes", RDKit::AtomCompareIsotopes)
.value("CompareAnyHeavyAtom", RDKit::AtomCompareAnyHeavyAtom);
python::enum_<RDKit::BondComparator>("BondCompare")
.value("CompareAny", RDKit::BondCompareAny)
.value("CompareOrder", RDKit::BondCompareOrder)

View File

@@ -171,6 +171,30 @@ class TestCase(unittest.TestCase):
for m in ms:
self.assertTrue(m.HasSubstructMatch(qm))
def testAtomCompareAnyHeavyAtom(self):
# H matches H, O matches C
smis = ('[H]c1ccccc1C', '[H]c1ccccc1O')
ms = [Chem.MolFromSmiles(x, sanitize=False) for x in smis]
mcs = rdFMCS.FindMCS(ms, atomCompare=rdFMCS.AtomCompare.CompareAnyHeavyAtom)
self.assertEqual(mcs.numBonds, 8)
self.assertEqual(mcs.numAtoms, 8)
qm = Chem.MolFromSmarts(mcs.smartsString)
for m in ms:
self.assertTrue(m.HasSubstructMatch(qm))
def testAtomCompareAnyHeavyAtom1(self):
# O matches C, H does not match O
smis = ('[H]c1ccccc1C', 'Oc1ccccc1O')
ms = [Chem.MolFromSmiles(x, sanitize=False) for x in smis]
mcs = rdFMCS.FindMCS(ms, atomCompare=rdFMCS.AtomCompare.CompareAnyHeavyAtom)
self.assertEqual(mcs.numBonds, 7)
self.assertEqual(mcs.numAtoms, 7)
qm = Chem.MolFromSmarts(mcs.smartsString)
for m in ms:
self.assertTrue(m.HasSubstructMatch(qm))
def test6MatchValences(self):
ms = (Chem.MolFromSmiles('NC1OC1'), Chem.MolFromSmiles('C1OC1[N+](=O)[O-]'))
mcs = rdFMCS.FindMCS(ms)

View File

@@ -585,6 +585,46 @@ void testAtomCompareAnyAtomBond() {
BOOST_LOG(rdInfoLog) << "\tdone" << std::endl;
}
void testAtomCompareAnyHeavyAtom() {
BOOST_LOG(rdInfoLog) << "-------------------------------------" << std::endl;
BOOST_LOG(rdInfoLog) << "Testing FMCS testAtomCompareAnyAtom" << std::endl;
std::cout << "\ntestAtomCompareAnyAtom()\n";
std::vector<ROMOL_SPTR> mols;
const char* smi[] = {
"[H]c1ccccc1C", "[H]c1ccccc1O", // H matches H, O matches C
};
for (auto& i : smi) mols.push_back(ROMOL_SPTR(SmilesToMol(getSmilesOnly(i),0,false)));
MCSParameters p;
p.AtomTyper = MCSAtomCompareAnyHeavyAtom;
t0 = nanoClock();
MCSResult res = findMCS(mols, &p);
std::cout << "MCS: " << res.SmartsString << " " << res.NumAtoms << " atoms, "
<< res.NumBonds << " bonds\n";
printTime();
TEST_ASSERT(res.NumAtoms == 8 && res.NumBonds == 8);
BOOST_LOG(rdInfoLog) << "\tdone" << std::endl;
}
void testAtomCompareAnyHeavyAtom1() {
BOOST_LOG(rdInfoLog) << "-------------------------------------" << std::endl;
BOOST_LOG(rdInfoLog) << "Testing FMCS testAtomCompareAnyAtom" << std::endl;
std::cout << "\ntestAtomCompareAnyAtom()\n";
std::vector<ROMOL_SPTR> mols;
const char* smi[] = {
"[H]c1ccccc1C", "Oc1ccccc1O", // O matches C, H does not match O
};
for (auto& i : smi) mols.push_back(ROMOL_SPTR(SmilesToMol(getSmilesOnly(i),0,false)));
MCSParameters p;
p.AtomTyper = MCSAtomCompareAnyHeavyAtom;
t0 = nanoClock();
MCSResult res = findMCS(mols, &p);
std::cout << "MCS: " << res.SmartsString << " " << res.NumAtoms << " atoms, "
<< res.NumBonds << " bonds\n";
printTime();
TEST_ASSERT(res.NumAtoms == 7 && res.NumBonds == 7);
BOOST_LOG(rdInfoLog) << "\tdone" << std::endl;
}
void testSimple() {
BOOST_LOG(rdInfoLog) << "-------------------------------------" << std::endl;
BOOST_LOG(rdInfoLog) << "Testing FMCS testSimple" << std::endl;
@@ -1376,6 +1416,8 @@ int main(int argc, const char* argv[]) {
testAtomCompareIsotopes();
testAtomCompareAnyAtom();
testAtomCompareAnyAtomBond();
testAtomCompareAnyHeavyAtom();
testAtomCompareAnyHeavyAtom1();
test18();
test504();

View File

@@ -86,6 +86,37 @@ public class FMCSTests extends GraphMolTest {
assertEquals(false,mcs.getCanceled());
}
@Test
public void testAtomCompareAnyHeavyAtom() {
ROMol_Vect mols = new ROMol_Vect();
mols.add(RWMol.MolFromSmiles("[H]c1ccccc1C",0, false));
mols.add(RWMol.MolFromSmiles("[H]c1ccccc1O",0, false));
// H matches H, O matches C
MCSResult mcs=RDKFuncs.findMCS(mols,true,1,60,false,false,false,false,false,
AtomComparator.AtomCompareAnyHeavyAtom,
BondComparator.BondCompareAny);
assertEquals(8,mcs.getNumAtoms());
assertEquals(8,mcs.getNumBonds());
//assertEquals("[#6]1:,-[#6]:,-[#6]:,-[#6]:,-[#6]:,-[#6]:,-1",mcs.getSmartsString());
assertEquals(false,mcs.getCanceled());
}
@Test
public void testAtomCompareAnyHeavyAtom1() {
ROMol_Vect mols = new ROMol_Vect();
mols.add(RWMol.MolFromSmiles("[H]c1ccccc1C",0, false));
mols.add(RWMol.MolFromSmiles("Oc1ccccc1O",0, false));
// O matches C, H does not match O
MCSResult mcs=RDKFuncs.findMCS(mols,true,1,60,false,false,false,false,false,
AtomComparator.AtomCompareAnyHeavyAtom,
BondComparator.BondCompareAny);
assertEquals(7,mcs.getNumAtoms());
assertEquals(7,mcs.getNumBonds());
//assertEquals("[#6]1:,-[#6]:,-[#6]:,-[#6]:,-[#6]:,-[#6]:,-1",mcs.getSmartsString());
assertEquals(false,mcs.getCanceled());
}
public static void main(String args[]) {
org.junit.runner.JUnitCore.main("org.RDKit.FMCSTests");