diff --git a/Code/GraphMol/SmilesParse/SmartsWrite.cpp b/Code/GraphMol/SmilesParse/SmartsWrite.cpp index 77065da7a..6446a99a1 100644 --- a/Code/GraphMol/SmilesParse/SmartsWrite.cpp +++ b/Code/GraphMol/SmilesParse/SmartsWrite.cpp @@ -410,7 +410,19 @@ std::string getBondSmartsSimple(const Bond *bond, } else if (descrip == "BondInRing") { res += "@"; } else if (descrip == "SingleOrAromaticBond") { - // don't need to do anything here... :-) + auto dir = bond->getBondDir(); + switch(dir) { + case Bond::ENDDOWNRIGHT: { + res += "\\"; + break; + } + case Bond::ENDUPRIGHT: { + res += "/"; + break; + } + default: + break; + } } else if (descrip == "SingleOrDoubleBond") { res += "-,="; } else if (descrip == "DoubleOrAromaticBond") { @@ -1040,4 +1052,4 @@ std::string MolFragmentToCXSmarts(const ROMol &mol, return res; } -} // namespace RDKit \ No newline at end of file +} // namespace RDKit diff --git a/Code/GraphMol/SmilesParse/lex.yysmarts.cpp.cmake b/Code/GraphMol/SmilesParse/lex.yysmarts.cpp.cmake index bec2ec0a6..c6ff0e64e 100644 --- a/Code/GraphMol/SmilesParse/lex.yysmarts.cpp.cmake +++ b/Code/GraphMol/SmilesParse/lex.yysmarts.cpp.cmake @@ -1733,6 +1733,7 @@ YY_RULE_SETUP #line 362 "smarts.ll" { yylval->bond = new QueryBond(Bond::SINGLE); yylval->bond->setBondDir(Bond::ENDDOWNRIGHT); + yylval->bond->setQuery(makeSingleOrAromaticBondQuery()); return BOND_TOKEN; } YY_BREAK case 153: @@ -1740,6 +1741,7 @@ YY_RULE_SETUP #line 366 "smarts.ll" { yylval->bond = new QueryBond(Bond::SINGLE); yylval->bond->setBondDir(Bond::ENDUPRIGHT); + yylval->bond->setQuery(makeSingleOrAromaticBondQuery()); return BOND_TOKEN; } YY_BREAK case 154: diff --git a/Code/GraphMol/SmilesParse/smarts.ll b/Code/GraphMol/SmilesParse/smarts.ll index 5de37432b..874a5a8a4 100644 --- a/Code/GraphMol/SmilesParse/smarts.ll +++ b/Code/GraphMol/SmilesParse/smarts.ll @@ -360,10 +360,12 @@ A { [\\]{1,2} { yylval->bond = new QueryBond(Bond::SINGLE); yylval->bond->setBondDir(Bond::ENDDOWNRIGHT); + yylval->bond->setQuery(makeSingleOrAromaticBondQuery()); return BOND_TOKEN; } [\/] { yylval->bond = new QueryBond(Bond::SINGLE); yylval->bond->setBondDir(Bond::ENDUPRIGHT); + yylval->bond->setQuery(makeSingleOrAromaticBondQuery()); return BOND_TOKEN; } \-\> { diff --git a/Code/GraphMol/SmilesParse/smatest.cpp b/Code/GraphMol/SmilesParse/smatest.cpp index 379e77978..54c409886 100644 --- a/Code/GraphMol/SmilesParse/smatest.cpp +++ b/Code/GraphMol/SmilesParse/smatest.cpp @@ -1167,6 +1167,16 @@ void testSmartsStereochem() { _checkMatches("C/C=C/C", "C/C=C/C", 1, 4); _checkMatches("C/C=C/C", "C\\C=C\\C", 1, 4); _checkMatches("C/C=C/C", "C/C=C\\C", 1, 4); + + // directional bonds are set to be a direction \ / + // and a query - SingleOrAromatic, make sure that this + // is their current representation + auto m1 = "C/C=C\\C"_smarts; + TEST_ASSERT(m1->getBondWithIdx(0)->hasQuery()); + TEST_ASSERT(m1->getBondWithIdx(0)->getQuery()->getDescription() == "SingleOrAromaticBond"); + + auto m2 = "O=c1/c(=C/c2ccccc2)sc2n1-N-C-N-N=2"_smarts; + TEST_ASSERT(MolToSmarts(*m2) == "O=c1/c(=C/c2ccccc2)sc2n1-N-C-N-N=2"); BOOST_LOG(rdInfoLog) << "\tdone" << std::endl; } diff --git a/Code/GraphMol/Substruct/catch_tests.cpp b/Code/GraphMol/Substruct/catch_tests.cpp index 0c007677a..cbf014fde 100644 --- a/Code/GraphMol/Substruct/catch_tests.cpp +++ b/Code/GraphMol/Substruct/catch_tests.cpp @@ -840,4 +840,18 @@ M END)CTAB"_ctab; CHECK(SubstructMatch(*m_single, *m_aromatic, ps).size() == 1); CHECK(SubstructMatch(*m_aromatic, *m_single, ps).size() == 1); } -} \ No newline at end of file +} + +TEST_CASE("Github #7295", "CIS/TRANS in aromatic ring") { + SECTION("Smart CIS/TRANS bonds should match single or aromatic"){ + SubstructMatchParameters ps; + + auto query = "[O:1]=[c:2]1/[c:3](=[C:4]/[c:5]2:[c:10]:[c:9]:[c:8]:[c:7]:[c:6]:2):[s:11]:[c:12]2:[n:13]:1-[N:14]-[C:15]-[N:20]-[N:21]=2"_smarts; + auto mol = "[O:1]=[c:2]1/[c:3](=[CH:4]/[c:5]2[cH:6][cH:7][cH:8][cH:9][cH:10]2)[s:11][c:12]2[n:13]1[NH:14][C:15]1([CH2:16][CH2:17][CH2:18][CH2:19]1)[NH:20][N:21]=2"_smiles; + CHECK(SubstructMatch(*mol, *query, ps).size() == 1); + ps.useChirality = true; + CHECK(SubstructMatch(*mol, *query, ps).size() == 1); + auto mol2 = "[O:1]=[c:2]1\\[c:3](=[CH:4]/[c:5]2[cH:6][cH:7][cH:8][cH:9][cH:10]2)[s:11][c:12]2[n:13]1[NH:14][C:15]1([CH2:16][CH2:17][CH2:18][CH2:19]1)[NH:20][N:21]=2"_smiles; + CHECK(SubstructMatch(*mol2, *query, ps).size() == 0); + } +}