mirror of
https://github.com/rdkit/rdkit.git
synced 2026-06-04 21:54:27 +08:00
* do not use new on loggers * del pointers in testDistGeom * Update Dict hasNonPOD status on bulk update * delete new Dicts in memtest1.cpp * fixes in MolSuppliers and testFMCS * PeriodicTable singleton as unique_ptr * fix EEM_arrays leak * fix leaks in testPBF * fix ParamCollection leak in test UFF * fix leaks in MMFF * clear prop dict before read in in pickler * fix leaks in testFreeSASA * fix leaks in test3D * modernize Dict.h & SmilesParse.cpp * fix leaks in testQuery * fix leaks in testCrystalFF * fix leaks in cxsmilesTest * fix leaks in Catalog & mol cat test * fix leaks in ShapeUtils & tests * fix leaks in testSubgraphs1 * fix leaks testFingerprintGenerators * fix leaks in Catalog/FilterCatalog * fix leaks in graphmolqueryTest * these changes reduce bison parse leaks * fixed leaks in testChirality.cpp * fix leaks + 2 tests in testMolWriter * fix 4m leaks in substructLibraryTest * small improvements to molTautomerTest; still leaks * fix leaks in testRGroupDecomp * fix leaks in test; parser still leaks * fix leaks in itertest * fix 4m leaks in testDepictor * fixes in smatest; still leaking due to parser * fixes in testSLNParse; still leaking due to parser * flex/bison: always add atoms with ownership; smarts error cleanup * fix leaks in testReaction * fix leaks in testSubstructMatch * fix leaks in resMolSupplierTest * fix leaks in testChemTransforms + bug in ChemTransforms * fix leaks in testPickler * fix leaks in testMolTransform * fix leaks in testFragCatalog * fix leak in testSLNParse. Still leaks due to Smiles * fixed most leaks in testMolSupplier * pre bison fix * fix some atom & bond parse problems; others still fail * bison smiles & smarts, atoms & bonds more or less fixed * fix leaks in molopstest.cpp * fix leaks in testFingerprints, MACCS.cpp & AtomPairs.cpp * fix leaks in moldraw2Dtest1 * fix leaks in testDescriptors * fix leaks in testInchi * fix leaks in testUFFForceFieldHelpers * fix leaks in hanoiTest & new_canon.h * fix leaks in testMMFFForceField * fix leaks in graphmolTest1 * fix leaks in testMMFFForceFieldHelpers * fix leaks in testDistGeomHelpers * fix leaks in testMolAlign * initialize occupancy & temp facto with default values * fix leak in TautomerTransform * updated suppressions * fix testStructChecker * fix logging & py tests * fix TautomerTransform class/struct issue * remove misplaced delete in testSLNParse * deinit in testAvalonLib1 * fix Avalon-triggered(?) bug in StructChecker/Pattern.cpp * fix random testMolWriter/Supplier fails - diversify output file names to avoid clashing. - unify Writers close/destruct behavior. - flushing/closing in tests. * use reset in FFs Params.cpp * comments on testMMFFForceField * unrequired 'if's added to mol suppliers * correct cast in FilterCatalog.h * use unique_ptr in MACCS Patterns * remove unrequred if in new_canon * update & move suppressions
807 lines
32 KiB
C++
807 lines
32 KiB
C++
//
|
|
// Copyright (C) 2018 Susan H. Leung
|
|
//
|
|
// @@ All Rights Reserved @@
|
|
// This file is part of the RDKit.
|
|
// The contents are covered by the terms of the BSD license
|
|
// which is included in the file license.txt, found at the root
|
|
// of the RDKit source tree.
|
|
//
|
|
#include "Tautomer.h"
|
|
#include <GraphMol/RDKitBase.h>
|
|
#include <GraphMol/SmilesParse/SmilesParse.h>
|
|
#include <GraphMol/SmilesParse/SmilesWrite.h>
|
|
|
|
using namespace RDKit;
|
|
using namespace MolStandardize;
|
|
|
|
void testEnumerator() {
|
|
BOOST_LOG(rdInfoLog)
|
|
<< "-----------------------\n Testing tautomer enumeration" << std::endl;
|
|
|
|
std::string rdbase = getenv("RDBASE");
|
|
std::string tautomerFile =
|
|
rdbase + "/Data/MolStandardize/tautomerTransforms.in";
|
|
auto tautparams = std::unique_ptr<TautomerCatalogParams>(new TautomerCatalogParams(tautomerFile));
|
|
unsigned int ntautomers = tautparams->getNumTautomers();
|
|
TEST_ASSERT(ntautomers == 34);
|
|
|
|
TautomerCatalog tautcat(tautparams.get());
|
|
TautomerEnumerator te;
|
|
|
|
// Enumerate 1,3 keto/enol tautomer.
|
|
std::string smi1 = "C1(=CCCCC1)O";
|
|
std::shared_ptr<ROMol> m1(SmilesToMol(smi1));
|
|
std::vector<ROMOL_SPTR> res = te.enumerate(*m1, &tautcat);
|
|
std::vector<std::string> ans = {"O=C1CCCCC1", "OC1=CCCCC1"};
|
|
TEST_ASSERT(res.size() == ans.size());
|
|
for (size_t i = 0; i < res.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res[i]) == ans[i]);
|
|
}
|
|
|
|
// Enumerate 1,3 keto/enol tautomer.
|
|
std::string smi2 = "C1(CCCCC1)=O";
|
|
std::shared_ptr<ROMol> m2(SmilesToMol(smi2));
|
|
std::vector<ROMOL_SPTR> res2 = te.enumerate(*m2, &tautcat);
|
|
std::vector<std::string> ans2 = {"O=C1CCCCC1", "OC1=CCCCC1"};
|
|
TEST_ASSERT(res2.size() == ans2.size());
|
|
for (size_t i = 0; i < res2.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res2[i]) == ans2[i]);
|
|
}
|
|
|
|
// Enumerate acetophenone keto/enol tautomer.
|
|
std::string smi3 = "C(=C)(O)C1=CC=CC=C1";
|
|
std::shared_ptr<ROMol> m3(SmilesToMol(smi3));
|
|
std::vector<ROMOL_SPTR> res3 = te.enumerate(*m3, &tautcat);
|
|
std::vector<std::string> ans3 = {"C=C(O)c1ccccc1", "CC(=O)c1ccccc1"};
|
|
TEST_ASSERT(res3.size() == ans3.size());
|
|
for (size_t i = 0; i < res3.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res3[i]) == ans3[i]);
|
|
}
|
|
|
|
// Enumerate acetone keto/enol tautomer.
|
|
std::string smi4 = "CC(C)=O";
|
|
std::shared_ptr<ROMol> m4(SmilesToMol(smi4));
|
|
std::vector<ROMOL_SPTR> res4 = te.enumerate(*m4, &tautcat);
|
|
std::vector<std::string> ans4 = {"C=C(C)O", "CC(C)=O"};
|
|
TEST_ASSERT(res4.size() == ans4.size());
|
|
for (size_t i = 0; i < res4.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res4[i]) == ans4[i]);
|
|
}
|
|
|
|
// keto/enol tautomer
|
|
std::string smi5 = "OC(C)=C(C)C";
|
|
std::shared_ptr<ROMol> m5(SmilesToMol(smi5));
|
|
std::vector<ROMOL_SPTR> res5 = te.enumerate(*m5, &tautcat);
|
|
std::vector<std::string> ans5 = {"C=C(O)C(C)C", "CC(=O)C(C)C", "CC(C)=C(C)O"};
|
|
TEST_ASSERT(res5.size() == ans5.size());
|
|
for (size_t i = 0; i < res5.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res5[i]) == ans5[i]);
|
|
}
|
|
|
|
// 1-phenyl-2-propanone enol/keto
|
|
std::string smi6 = "c1(ccccc1)CC(=O)C";
|
|
std::shared_ptr<ROMol> m6(SmilesToMol(smi6));
|
|
std::vector<ROMOL_SPTR> res6 = te.enumerate(*m6, &tautcat);
|
|
std::vector<std::string> ans6 = {"C=C(O)Cc1ccccc1", "CC(=O)Cc1ccccc1",
|
|
"CC(O)=Cc1ccccc1"};
|
|
TEST_ASSERT(res6.size() == ans6.size());
|
|
for (size_t i = 0; i < res6.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res6[i]) == ans6[i]);
|
|
}
|
|
|
|
// 1,5 keto/enol tautomer
|
|
std::string smi7 = "Oc1nccc2cc[nH]c(=N)c12";
|
|
std::shared_ptr<ROMol> m7(SmilesToMol(smi7));
|
|
std::vector<ROMOL_SPTR> res7 = te.enumerate(*m7, &tautcat);
|
|
std::vector<std::string> ans7 = {
|
|
"N=c1[nH]ccc2cc[nH]c(=O)c12", "N=c1[nH]ccc2ccnc(O)c12",
|
|
"N=c1nccc2cc[nH]c(O)c1-2", "Nc1[nH]ccc2ccnc(=O)c1-2",
|
|
"Nc1nccc2cc[nH]c(=O)c12", "Nc1nccc2ccnc(O)c12"};
|
|
TEST_ASSERT(res7.size() == ans7.size());
|
|
for (size_t i = 0; i < res7.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res7[i]) == ans7[i]);
|
|
}
|
|
|
|
// 1,5 keto/enol tautomer
|
|
std::string smi8 = "C1(C=CCCC1)=O";
|
|
std::shared_ptr<ROMol> m8(SmilesToMol(smi8));
|
|
std::vector<ROMOL_SPTR> res8 = te.enumerate(*m8, &tautcat);
|
|
std::vector<std::string> ans8 = {"O=C1C=CCCC1", "O=C1CC=CCC1", "OC1=CC=CCC1",
|
|
"OC1=CCC=CC1", "OC1=CCCC=C1"};
|
|
TEST_ASSERT(res8.size() == ans8.size());
|
|
for (size_t i = 0; i < res8.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res8[i]) == ans8[i]);
|
|
}
|
|
|
|
// 1,5 keto/enol tautomer
|
|
std::string smi9 = "C1(=CC=CCC1)O";
|
|
std::shared_ptr<ROMol> m9(SmilesToMol(smi9));
|
|
std::vector<ROMOL_SPTR> res9 = te.enumerate(*m9, &tautcat);
|
|
std::vector<std::string> ans9 = {"O=C1C=CCCC1", "O=C1CC=CCC1", "OC1=CC=CCC1",
|
|
"OC1=CCC=CC1", "OC1=CCCC=C1"};
|
|
TEST_ASSERT(res9.size() == ans9.size());
|
|
for (size_t i = 0; i < res9.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res9[i]) == ans9[i]);
|
|
}
|
|
|
|
// aliphatic imine tautomer
|
|
std::string smi10 = "C1(CCCCC1)=N";
|
|
std::shared_ptr<ROMol> m10(SmilesToMol(smi10));
|
|
std::vector<ROMOL_SPTR> res10 = te.enumerate(*m10, &tautcat);
|
|
std::vector<std::string> ans10 = {"N=C1CCCCC1", "NC1=CCCCC1"};
|
|
TEST_ASSERT(res10.size() == ans10.size());
|
|
for (size_t i = 0; i < res10.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res10[i]) == ans10[i]);
|
|
}
|
|
|
|
// aliphatic imine tautomer
|
|
std::string smi11 = "C1(=CCCCC1)N";
|
|
std::shared_ptr<ROMol> m11(SmilesToMol(smi11));
|
|
std::vector<ROMOL_SPTR> res11 = te.enumerate(*m11, &tautcat);
|
|
std::vector<std::string> ans11 = {"N=C1CCCCC1", "NC1=CCCCC1"};
|
|
TEST_ASSERT(res11.size() == ans11.size());
|
|
for (size_t i = 0; i < res11.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res11[i]) == ans11[i]);
|
|
}
|
|
|
|
// special imine tautomer
|
|
std::string smi12 = "C1(C=CC=CN1)=CC";
|
|
std::shared_ptr<ROMol> m12(SmilesToMol(smi12));
|
|
std::vector<ROMOL_SPTR> res12 = te.enumerate(*m12, &tautcat);
|
|
std::vector<std::string> ans12 = {"CC=C1C=CC=CN1", "CC=C1C=CCC=N1",
|
|
"CCc1ccccn1"};
|
|
TEST_ASSERT(res12.size() == ans12.size());
|
|
for (size_t i = 0; i < res12.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res12[i]) == ans12[i]);
|
|
}
|
|
|
|
// special imine tautomer
|
|
std::string smi13 = "C1(=NC=CC=C1)CC";
|
|
std::shared_ptr<ROMol> m13(SmilesToMol(smi13));
|
|
std::vector<ROMOL_SPTR> res13 = te.enumerate(*m13, &tautcat);
|
|
std::vector<std::string> ans13 = {"CC=C1C=CC=CN1", "CC=C1C=CCC=N1",
|
|
"CCc1ccccn1"};
|
|
TEST_ASSERT(res13.size() == ans13.size());
|
|
for (size_t i = 0; i < res13.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res13[i]) == ans13[i]);
|
|
}
|
|
|
|
// 1,3 aromatic heteroatom H shift
|
|
std::string smi14 = "O=c1cccc[nH]1";
|
|
std::shared_ptr<ROMol> m14(SmilesToMol(smi14));
|
|
std::vector<ROMOL_SPTR> res14 = te.enumerate(*m14, &tautcat);
|
|
std::vector<std::string> ans14 = {"O=c1cccc[nH]1", "Oc1ccccn1"};
|
|
TEST_ASSERT(res14.size() == ans14.size());
|
|
for (size_t i = 0; i < res14.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res14[i]) == ans14[i]);
|
|
}
|
|
|
|
// 1,3 aromatic heteroatom H shift
|
|
std::string smi15 = "Oc1ccccn1";
|
|
std::shared_ptr<ROMol> m15(SmilesToMol(smi15));
|
|
std::vector<ROMOL_SPTR> res15 = te.enumerate(*m15, &tautcat);
|
|
std::vector<std::string> ans15 = {"O=c1cccc[nH]1", "Oc1ccccn1"};
|
|
TEST_ASSERT(res15.size() == ans15.size());
|
|
for (size_t i = 0; i < res15.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res15[i]) == ans15[i]);
|
|
}
|
|
|
|
// 1,3 aromatic heteroatom H shift
|
|
std::string smi16 = "Oc1ncc[nH]1";
|
|
std::shared_ptr<ROMol> m16(SmilesToMol(smi16));
|
|
std::vector<ROMOL_SPTR> res16 = te.enumerate(*m16, &tautcat);
|
|
std::vector<std::string> ans16 = {"O=c1[nH]cc[nH]1", "Oc1ncc[nH]1"};
|
|
TEST_ASSERT(res16.size() == ans16.size());
|
|
for (size_t i = 0; i < res16.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res16[i]) == ans16[i]);
|
|
}
|
|
|
|
// 1,3 heteroatom H shift
|
|
std::string smi17 = "OC(C)=NC";
|
|
std::shared_ptr<ROMol> m17(SmilesToMol(smi17));
|
|
std::vector<ROMOL_SPTR> res17 = te.enumerate(*m17, &tautcat);
|
|
std::vector<std::string> ans17 = {"C=C(O)NC", "CN=C(C)O", "CNC(C)=O"};
|
|
TEST_ASSERT(res17.size() == ans17.size());
|
|
for (size_t i = 0; i < res17.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res17[i]) == ans17[i]);
|
|
}
|
|
|
|
// 1,3 heteroatom H shift
|
|
std::string smi18 = "CNC(C)=O";
|
|
std::shared_ptr<ROMol> m18(SmilesToMol(smi18));
|
|
std::vector<ROMOL_SPTR> res18 = te.enumerate(*m18, &tautcat);
|
|
std::vector<std::string> ans18 = {"C=C(O)NC", "CN=C(C)O", "CNC(C)=O"};
|
|
TEST_ASSERT(res18.size() == ans18.size());
|
|
for (size_t i = 0; i < res18.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res18[i]) == ans18[i]);
|
|
}
|
|
|
|
// 1,3 heteroatom H shift
|
|
std::string smi19 = "S=C(N)N";
|
|
std::shared_ptr<ROMol> m19(SmilesToMol(smi19));
|
|
std::vector<ROMOL_SPTR> res19 = te.enumerate(*m19, &tautcat);
|
|
std::vector<std::string> ans19 = {"N=C(N)S", "NC(N)=S"};
|
|
TEST_ASSERT(res19.size() == ans19.size());
|
|
for (size_t i = 0; i < res19.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res19[i]) == ans19[i]);
|
|
}
|
|
|
|
// 1,3 heteroatom H shift
|
|
std::string smi20 = "SC(N)=N";
|
|
std::shared_ptr<ROMol> m20(SmilesToMol(smi20));
|
|
std::vector<ROMOL_SPTR> res20 = te.enumerate(*m20, &tautcat);
|
|
std::vector<std::string> ans20 = {"N=C(N)S", "NC(N)=S"};
|
|
TEST_ASSERT(res20.size() == ans20.size());
|
|
for (size_t i = 0; i < res20.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res20[i]) == ans20[i]);
|
|
}
|
|
|
|
// 1,3 heteroatom H shift
|
|
std::string smi21 = "N=c1[nH]ccn(C)1";
|
|
std::shared_ptr<ROMol> m21(SmilesToMol(smi21));
|
|
std::vector<ROMOL_SPTR> res21 = te.enumerate(*m21, &tautcat);
|
|
std::vector<std::string> ans21 = {"Cn1cc[nH]c1=N", "Cn1ccnc1N"};
|
|
TEST_ASSERT(res21.size() == ans21.size());
|
|
for (size_t i = 0; i < res21.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res21[i]) == ans21[i]);
|
|
}
|
|
|
|
// 1,3 heteroatom H shift
|
|
std::string smi22 = "CN=c1[nH]cncc1";
|
|
std::shared_ptr<ROMol> m22(SmilesToMol(smi22));
|
|
std::vector<ROMOL_SPTR> res22 = te.enumerate(*m22, &tautcat);
|
|
std::vector<std::string> ans22 = {"CN=c1cc[nH]cn1", "CN=c1ccnc[nH]1",
|
|
"CNc1ccncn1"};
|
|
TEST_ASSERT(res22.size() == ans22.size());
|
|
for (size_t i = 0; i < res22.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res22[i]) == ans22[i]);
|
|
}
|
|
|
|
// 1,5 aromatic heteroatom H shift
|
|
std::string smi23 = "Oc1cccc2ccncc12";
|
|
std::shared_ptr<ROMol> m23(SmilesToMol(smi23));
|
|
std::vector<ROMOL_SPTR> res23 = te.enumerate(*m23, &tautcat);
|
|
std::vector<std::string> ans23 = {"O=c1cccc2cc[nH]cc1-2", "Oc1cccc2ccncc12"};
|
|
TEST_ASSERT(res23.size() == ans23.size());
|
|
for (size_t i = 0; i < res23.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res23[i]) == ans23[i]);
|
|
}
|
|
|
|
// 1,5 aromatic heteroatom H shift
|
|
std::string smi24 = "O=c1cccc2cc[nH]cc1-2";
|
|
std::shared_ptr<ROMol> m24(SmilesToMol(smi24));
|
|
std::vector<ROMOL_SPTR> res24 = te.enumerate(*m24, &tautcat);
|
|
std::vector<std::string> ans24 = {"O=c1cccc2cc[nH]cc1-2", "Oc1cccc2ccncc12"};
|
|
TEST_ASSERT(res24.size() == ans24.size());
|
|
for (size_t i = 0; i < res24.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res24[i]) == ans24[i]);
|
|
}
|
|
|
|
// 1,5 aromatic heteroatom H shift
|
|
std::string smi25 = "Cc1n[nH]c2ncnn12";
|
|
std::shared_ptr<ROMol> m25(SmilesToMol(smi25));
|
|
std::vector<ROMOL_SPTR> res25 = te.enumerate(*m25, &tautcat);
|
|
std::vector<std::string> ans25 = {"C=C1NN=C2N=CNN12", "C=C1NN=C2NC=NN12",
|
|
"C=C1NNc2ncnn21", "Cc1n[nH]c2ncnn12",
|
|
"Cc1nnc2[nH]cnn12", "Cc1nnc2nc[nH]n12"};
|
|
TEST_ASSERT(res25.size() == ans25.size());
|
|
for (size_t i = 0; i < res25.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res25[i]) == ans25[i]);
|
|
}
|
|
|
|
// 1,5 aromatic heteroatom H shift
|
|
std::string smi26 = "Cc1nnc2nc[nH]n12";
|
|
std::shared_ptr<ROMol> m26(SmilesToMol(smi26));
|
|
std::vector<ROMOL_SPTR> res26 = te.enumerate(*m26, &tautcat);
|
|
std::vector<std::string> ans26 = {"C=C1NN=C2N=CNN12", "C=C1NN=C2NC=NN12",
|
|
"C=C1NNc2ncnn21", "Cc1n[nH]c2ncnn12",
|
|
"Cc1nnc2[nH]cnn12", "Cc1nnc2nc[nH]n12"};
|
|
TEST_ASSERT(res26.size() == ans26.size());
|
|
for (size_t i = 0; i < res26.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res26[i]) == ans26[i]);
|
|
}
|
|
|
|
// 1,5 aromatic heteroatom H shift
|
|
std::string smi29 = "Oc1ccncc1";
|
|
std::shared_ptr<ROMol> m29(SmilesToMol(smi29));
|
|
std::vector<ROMOL_SPTR> res29 = te.enumerate(*m29, &tautcat);
|
|
std::vector<std::string> ans29 = {"O=c1cc[nH]cc1", "Oc1ccncc1"};
|
|
TEST_ASSERT(res29.size() == ans29.size());
|
|
for (size_t i = 0; i < res29.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res29[i]) == ans29[i]);
|
|
}
|
|
|
|
// 1,5 aromatic heteroatom H shift
|
|
std::string smi27 = "Oc1c(cccc3)c3nc2ccncc12";
|
|
std::shared_ptr<ROMol> m27(SmilesToMol(smi27));
|
|
std::vector<ROMOL_SPTR> res27 = te.enumerate(*m27, &tautcat);
|
|
std::vector<std::string> ans27 = {"O=c1c2c[nH]ccc-2nc2ccccc12",
|
|
"O=c1c2ccccc2[nH]c2ccncc12",
|
|
"Oc1c2ccccc2nc2ccncc12"};
|
|
TEST_ASSERT(res27.size() == ans27.size());
|
|
for (size_t i = 0; i < res27.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res27[i]) == ans27[i]);
|
|
}
|
|
|
|
// 1,3 and 1,5 aromatic heteroatom H shift
|
|
std::string smi28 = "Oc1ncncc1";
|
|
std::shared_ptr<ROMol> m28(SmilesToMol(smi28));
|
|
std::vector<ROMOL_SPTR> res28 = te.enumerate(*m28, &tautcat);
|
|
std::vector<std::string> ans28 = {"O=c1cc[nH]cn1", "O=c1ccnc[nH]1",
|
|
"Oc1ccncn1"};
|
|
TEST_ASSERT(res28.size() == ans28.size());
|
|
for (size_t i = 0; i < res28.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res28[i]) == ans28[i]);
|
|
}
|
|
|
|
// 1,5 aromatic heteroatom H shift
|
|
std::string smi30 = "C2(=C1C(=NC=N1)[NH]C(=N2)N)O";
|
|
std::shared_ptr<ROMol> m30(SmilesToMol(smi30));
|
|
std::vector<ROMOL_SPTR> res30 = te.enumerate(*m30, &tautcat);
|
|
std::vector<std::string> ans30 = {
|
|
"N=c1[nH]c(=O)c2[nH]cnc2[nH]1", "N=c1[nH]c(=O)c2nc[nH]c2[nH]1",
|
|
"N=c1[nH]c2ncnc-2c(O)[nH]1", "N=c1nc(O)c2[nH]cnc2[nH]1",
|
|
"N=c1nc(O)c2nc[nH]c2[nH]1", "N=c1nc2[nH]cnc2c(O)[nH]1",
|
|
"N=c1nc2nc[nH]c2c(O)[nH]1", "Nc1nc(=O)c2[nH]cnc2[nH]1",
|
|
"Nc1nc(=O)c2nc[nH]c2[nH]1", "Nc1nc(O)c2[nH]cnc2n1",
|
|
"Nc1nc(O)c2nc[nH]c2n1", "Nc1nc(O)c2ncnc-2[nH]1",
|
|
"Nc1nc2[nH]cnc2c(=O)[nH]1", "Nc1nc2nc[nH]c2c(=O)[nH]1",
|
|
"Nc1nc2ncnc-2c(O)[nH]1"};
|
|
TEST_ASSERT(res30.size() == ans30.size());
|
|
for (size_t i = 0; i < res30.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res30[i]) == ans30[i]);
|
|
}
|
|
|
|
// 1,5 aromatic heteroatom H shift
|
|
std::string smi31 = "C2(C1=C([NH]C=N1)[NH]C(=N2)N)=O";
|
|
std::shared_ptr<ROMol> m31(SmilesToMol(smi31));
|
|
std::vector<ROMOL_SPTR> res31 = te.enumerate(*m31, &tautcat);
|
|
std::vector<std::string> ans31 = {
|
|
"N=c1[nH]c(=O)c2[nH]cnc2[nH]1", "N=c1[nH]c(=O)c2nc[nH]c2[nH]1",
|
|
"N=c1[nH]c2ncnc-2c(O)[nH]1", "N=c1nc(O)c2[nH]cnc2[nH]1",
|
|
"N=c1nc(O)c2nc[nH]c2[nH]1", "N=c1nc2[nH]cnc2c(O)[nH]1",
|
|
"N=c1nc2nc[nH]c2c(O)[nH]1", "Nc1nc(=O)c2[nH]cnc2[nH]1",
|
|
"Nc1nc(=O)c2nc[nH]c2[nH]1", "Nc1nc(O)c2[nH]cnc2n1",
|
|
"Nc1nc(O)c2nc[nH]c2n1", "Nc1nc(O)c2ncnc-2[nH]1",
|
|
"Nc1nc2[nH]cnc2c(=O)[nH]1", "Nc1nc2nc[nH]c2c(=O)[nH]1",
|
|
"Nc1nc2ncnc-2c(O)[nH]1"};
|
|
TEST_ASSERT(res31.size() == ans31.size());
|
|
for (size_t i = 0; i < res31.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res31[i]) == ans31[i]);
|
|
}
|
|
|
|
// 1,5 aromatic heteroatom H shift
|
|
std::string smi32 = "Oc1n(C)ncc1";
|
|
std::shared_ptr<ROMol> m32(SmilesToMol(smi32));
|
|
std::vector<ROMOL_SPTR> res32 = te.enumerate(*m32, &tautcat);
|
|
std::vector<std::string> ans32 = {"CN1N=CCC1=O", "Cn1[nH]ccc1=O",
|
|
"Cn1nccc1O"};
|
|
TEST_ASSERT(res32.size() == ans32.size());
|
|
for (size_t i = 0; i < res32.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res32[i]) == ans32[i]);
|
|
}
|
|
|
|
// 1,5 aromatic heteroatom H shift
|
|
std::string smi33 = "O=c1nc2[nH]ccn2cc1";
|
|
std::shared_ptr<ROMol> m33(SmilesToMol(smi33));
|
|
std::vector<ROMOL_SPTR> res33 = te.enumerate(*m33, &tautcat);
|
|
std::vector<std::string> ans33 = {"O=c1ccn2cc[nH]c2n1", "O=c1ccn2ccnc2[nH]1",
|
|
"Oc1ccn2ccnc2n1"};
|
|
TEST_ASSERT(res33.size() == ans33.size());
|
|
for (size_t i = 0; i < res33.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res33[i]) == ans33[i]);
|
|
}
|
|
|
|
// 1,5 aromatic heteroatom H shift
|
|
std::string smi34 = "N=c1nc[nH]cc1";
|
|
std::shared_ptr<ROMol> m34(SmilesToMol(smi34));
|
|
std::vector<ROMOL_SPTR> res34 = te.enumerate(*m34, &tautcat);
|
|
std::vector<std::string> ans34 = {"N=c1cc[nH]cn1", "N=c1ccnc[nH]1",
|
|
"Nc1ccncn1"};
|
|
TEST_ASSERT(res34.size() == ans34.size());
|
|
for (size_t i = 0; i < res34.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res34[i]) == ans34[i]);
|
|
}
|
|
|
|
// 1,5 aromatic heteroatom H shift
|
|
std::string smi35 = "N=c(c1)ccn2cc[nH]c12";
|
|
std::shared_ptr<ROMol> m35(SmilesToMol(smi35));
|
|
std::vector<ROMOL_SPTR> res35 = te.enumerate(*m35, &tautcat);
|
|
std::vector<std::string> ans35 = {"N=c1ccn2cc[nH]c2c1", "Nc1ccn2ccnc2c1"};
|
|
TEST_ASSERT(res35.size() == ans35.size());
|
|
for (size_t i = 0; i < res35.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res35[i]) == ans35[i]);
|
|
}
|
|
|
|
// 1,5 aromatic heteroatom H shift
|
|
std::string smi36 = "CN=c1nc[nH]cc1";
|
|
std::shared_ptr<ROMol> m36(SmilesToMol(smi36));
|
|
std::vector<ROMOL_SPTR> res36 = te.enumerate(*m36, &tautcat);
|
|
std::vector<std::string> ans36 = {"CN=c1cc[nH]cn1", "CN=c1ccnc[nH]1",
|
|
"CNc1ccncn1"};
|
|
TEST_ASSERT(res36.size() == ans36.size());
|
|
for (size_t i = 0; i < res36.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res36[i]) == ans36[i]);
|
|
}
|
|
|
|
// 1,7 aromatic heteroatom H shift
|
|
std::string smi37 = "c1ccc2[nH]c(-c3nc4ccccc4[nH]3)nc2c1";
|
|
std::shared_ptr<ROMol> m37(SmilesToMol(smi37));
|
|
std::vector<ROMOL_SPTR> res37 = te.enumerate(*m37, &tautcat);
|
|
std::vector<std::string> ans37 = {"c1ccc2[nH]c(-c3nc4ccccc4[nH]3)nc2c1",
|
|
"c1ccc2c(c1)=NC(c1nc3ccccc3[nH]1)N=2",
|
|
"c1ccc2c(c1)NC(=C1N=c3ccccc3=N1)N2"};
|
|
TEST_ASSERT(res37.size() == ans37.size());
|
|
for (size_t i = 0; i < res37.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res37[i]) == ans37[i]);
|
|
}
|
|
|
|
// 1,7 aromatic heteroatom H shift
|
|
std::string smi38 = "c1ccc2c(c1)NC(=C1N=c3ccccc3=N1)N2";
|
|
std::shared_ptr<ROMol> m38(SmilesToMol(smi38));
|
|
std::vector<ROMOL_SPTR> res38 = te.enumerate(*m38, &tautcat);
|
|
std::vector<std::string> ans38 = {"c1ccc2[nH]c(-c3nc4ccccc4[nH]3)nc2c1",
|
|
"c1ccc2c(c1)=NC(c1nc3ccccc3[nH]1)N=2",
|
|
"c1ccc2c(c1)NC(=C1N=c3ccccc3=N1)N2"};
|
|
TEST_ASSERT(res38.size() == ans38.size());
|
|
for (size_t i = 0; i < res38.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res38[i]) == ans38[i]);
|
|
}
|
|
|
|
// 1,9 aromatic heteroatom H shift
|
|
std::string smi39 = "CNc1ccnc2ncnn21";
|
|
std::shared_ptr<ROMol> m39(SmilesToMol(smi39));
|
|
std::vector<ROMOL_SPTR> res39 = te.enumerate(*m39, &tautcat);
|
|
std::vector<std::string> ans39 = {"CN=c1cc[nH]c2ncnn12",
|
|
"CN=c1ccnc2[nH]cnn12",
|
|
"CN=c1ccnc2nc[nH]n12", "CNc1ccnc2ncnn12"};
|
|
TEST_ASSERT(res39.size() == ans39.size());
|
|
for (size_t i = 0; i < res39.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res39[i]) == ans39[i]);
|
|
}
|
|
|
|
// 1,9 aromatic heteroatom H shift
|
|
std::string smi40 = "CN=c1ccnc2nc[nH]n21";
|
|
std::shared_ptr<ROMol> m40(SmilesToMol(smi40));
|
|
std::vector<ROMOL_SPTR> res40 = te.enumerate(*m40, &tautcat);
|
|
std::vector<std::string> ans40 = {"CN=c1cc[nH]c2ncnn12",
|
|
"CN=c1ccnc2[nH]cnn12",
|
|
"CN=c1ccnc2nc[nH]n12", "CNc1ccnc2ncnn12"};
|
|
TEST_ASSERT(res40.size() == ans40.size());
|
|
for (size_t i = 0; i < res40.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res40[i]) == ans40[i]);
|
|
}
|
|
|
|
// 1,11 aromatic heteroatom H shift
|
|
std::string smi41 = "Nc1ccc(C=C2C=CC(=O)C=C2)cc1";
|
|
std::shared_ptr<ROMol> m41(SmilesToMol(smi41));
|
|
std::vector<ROMOL_SPTR> res41 = te.enumerate(*m41, &tautcat);
|
|
std::vector<std::string> ans41 = {
|
|
"N=C1C=CC(=CC2C=CC(=O)C=C2)C=C1", "N=C1C=CC(=Cc2ccc(O)cc2)C=C1",
|
|
"N=C1C=CC(C=C2C=CC(=O)C=C2)C=C1", "Nc1ccc(C=C2C=CC(=O)C=C2)cc1"};
|
|
TEST_ASSERT(res41.size() == ans41.size());
|
|
for (size_t i = 0; i < res41.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res41[i]) == ans41[i]);
|
|
}
|
|
|
|
// 1,11 aromatic heteroatom H shift
|
|
std::string smi42 = "N=C1C=CC(=Cc2ccc(O)cc2)C=C1";
|
|
std::shared_ptr<ROMol> m42(SmilesToMol(smi42));
|
|
std::vector<ROMOL_SPTR> res42 = te.enumerate(*m42, &tautcat);
|
|
std::vector<std::string> ans42 = {
|
|
"N=C1C=CC(=CC2C=CC(=O)C=C2)C=C1", "N=C1C=CC(=Cc2ccc(O)cc2)C=C1",
|
|
"N=C1C=CC(C=C2C=CC(=O)C=C2)C=C1", "Nc1ccc(C=C2C=CC(=O)C=C2)cc1"};
|
|
TEST_ASSERT(res42.size() == ans42.size());
|
|
for (size_t i = 0; i < res42.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res42[i]) == ans42[i]);
|
|
}
|
|
|
|
// heterocyclic tautomer
|
|
std::string smi43 = "n1ccc2ccc[nH]c12";
|
|
std::shared_ptr<ROMol> m43(SmilesToMol(smi43));
|
|
std::vector<ROMOL_SPTR> res43 = te.enumerate(*m43, &tautcat);
|
|
std::vector<std::string> ans43 = {"c1c[nH]c2nccc-2c1", "c1cnc2[nH]ccc2c1"};
|
|
TEST_ASSERT(res43.size() == ans43.size());
|
|
for (size_t i = 0; i < res43.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res43[i]) == ans43[i]);
|
|
}
|
|
|
|
// heterocyclic tautomer
|
|
std::string smi44 = "c1cc(=O)[nH]c2nccn12";
|
|
std::shared_ptr<ROMol> m44(SmilesToMol(smi44));
|
|
std::vector<ROMOL_SPTR> res44 = te.enumerate(*m44, &tautcat);
|
|
std::vector<std::string> ans44 = {"O=c1ccn2cc[nH]c2n1", "O=c1ccn2ccnc2[nH]1",
|
|
"Oc1ccn2ccnc2n1"};
|
|
TEST_ASSERT(res44.size() == ans44.size());
|
|
for (size_t i = 0; i < res44.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res44[i]) == ans44[i]);
|
|
}
|
|
|
|
// heterocyclic tautomer
|
|
std::string smi45 = "c1cnc2c[nH]ccc12";
|
|
std::shared_ptr<ROMol> m45(SmilesToMol(smi45));
|
|
std::vector<ROMOL_SPTR> res45 = te.enumerate(*m45, &tautcat);
|
|
std::vector<std::string> ans45 = {"c1cc2cc[nH]c2cn1", "c1cc2cc[nH]cc-2n1"};
|
|
TEST_ASSERT(res45.size() == ans45.size());
|
|
for (size_t i = 0; i < res45.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res45[i]) == ans45[i]);
|
|
}
|
|
|
|
// heterocyclic tautomer
|
|
std::string smi46 = "n1ccc2c[nH]ccc12";
|
|
std::shared_ptr<ROMol> m46(SmilesToMol(smi46));
|
|
std::vector<ROMOL_SPTR> res46 = te.enumerate(*m46, &tautcat);
|
|
std::vector<std::string> ans46 = {"c1cc2[nH]ccc2cn1", "c1cc2c[nH]ccc-2n1"};
|
|
TEST_ASSERT(res46.size() == ans46.size());
|
|
for (size_t i = 0; i < res46.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res46[i]) == ans46[i]);
|
|
}
|
|
|
|
// heterocyclic tautomer
|
|
std::string smi47 = "c1cnc2ccc[nH]c12";
|
|
std::shared_ptr<ROMol> m47(SmilesToMol(smi47));
|
|
std::vector<ROMOL_SPTR> res47 = te.enumerate(*m47, &tautcat);
|
|
std::vector<std::string> ans47 = {"c1c[nH]c2ccnc-2c1", "c1cnc2cc[nH]c2c1"};
|
|
TEST_ASSERT(res47.size() == ans47.size());
|
|
for (size_t i = 0; i < res47.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res47[i]) == ans47[i]);
|
|
}
|
|
|
|
// furanone tautomer
|
|
std::string smi48 = "C1=CC=C(O1)O";
|
|
std::shared_ptr<ROMol> m48(SmilesToMol(smi48));
|
|
std::vector<ROMOL_SPTR> res48 = te.enumerate(*m48, &tautcat);
|
|
std::vector<std::string> ans48 = {"O=C1CC=CO1", "Oc1ccco1"};
|
|
TEST_ASSERT(res48.size() == ans48.size());
|
|
for (size_t i = 0; i < res48.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res48[i]) == ans48[i]);
|
|
}
|
|
|
|
// furanone tautomer
|
|
std::string smi49 = "O=C1CC=CO1";
|
|
std::shared_ptr<ROMol> m49(SmilesToMol(smi49));
|
|
std::vector<ROMOL_SPTR> res49 = te.enumerate(*m49, &tautcat);
|
|
std::vector<std::string> ans49 = {"O=C1CC=CO1", "Oc1ccco1"};
|
|
TEST_ASSERT(res49.size() == ans49.size());
|
|
for (size_t i = 0; i < res49.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res49[i]) == ans49[i]);
|
|
}
|
|
|
|
// keten/ynol tautomer
|
|
std::string smi50 = "CC=C=O";
|
|
std::shared_ptr<ROMol> m50(SmilesToMol(smi50));
|
|
std::vector<ROMOL_SPTR> res50 = te.enumerate(*m50, &tautcat);
|
|
std::vector<std::string> ans50 = {"CC#CO", "CC=C=O"};
|
|
TEST_ASSERT(res50.size() == ans50.size());
|
|
for (size_t i = 0; i < res50.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res50[i]) == ans50[i]);
|
|
}
|
|
|
|
// keten/ynol tautomer
|
|
std::string smi51 = "CC#CO";
|
|
std::shared_ptr<ROMol> m51(SmilesToMol(smi51));
|
|
std::vector<ROMOL_SPTR> res51 = te.enumerate(*m51, &tautcat);
|
|
std::vector<std::string> ans51 = {"CC#CO", "CC=C=O"};
|
|
TEST_ASSERT(res51.size() == ans51.size());
|
|
for (size_t i = 0; i < res51.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res51[i]) == ans51[i]);
|
|
}
|
|
|
|
// ionic nitro/aci-nitro tautomer
|
|
std::string smi52 = "C([N+](=O)[O-])C";
|
|
std::shared_ptr<ROMol> m52(SmilesToMol(smi52));
|
|
std::vector<ROMOL_SPTR> res52 = te.enumerate(*m52, &tautcat);
|
|
std::vector<std::string> ans52 = {"CC=[N+]([O-])O", "CC[N+](=O)[O-]"};
|
|
TEST_ASSERT(res52.size() == ans52.size());
|
|
for (size_t i = 0; i < res52.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res52[i]) == ans52[i]);
|
|
}
|
|
|
|
// ionic nitro/aci-nitro tautomer
|
|
std::string smi53 = "C(=[N+](O)[O-])C";
|
|
std::shared_ptr<ROMol> m53(SmilesToMol(smi53));
|
|
std::vector<ROMOL_SPTR> res53 = te.enumerate(*m53, &tautcat);
|
|
std::vector<std::string> ans53 = {"CC=[N+]([O-])O", "CC[N+](=O)[O-]"};
|
|
TEST_ASSERT(res53.size() == ans53.size());
|
|
for (size_t i = 0; i < res53.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res53[i]) == ans53[i]);
|
|
}
|
|
|
|
// oxim nitroso tautomer
|
|
std::string smi54 = "CC(C)=NO";
|
|
std::shared_ptr<ROMol> m54(SmilesToMol(smi54));
|
|
std::vector<ROMOL_SPTR> res54 = te.enumerate(*m54, &tautcat);
|
|
std::vector<std::string> ans54 = {"C=C(C)NO", "CC(C)=NO", "CC(C)N=O"};
|
|
TEST_ASSERT(res54.size() == ans54.size());
|
|
for (size_t i = 0; i < res54.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res54[i]) == ans54[i]);
|
|
}
|
|
|
|
// oxim nitroso tautomer
|
|
std::string smi55 = "CC(C)N=O";
|
|
std::shared_ptr<ROMol> m55(SmilesToMol(smi55));
|
|
std::vector<ROMOL_SPTR> res55 = te.enumerate(*m55, &tautcat);
|
|
std::vector<std::string> ans55 = {"C=C(C)NO", "CC(C)=NO", "CC(C)N=O"};
|
|
TEST_ASSERT(res55.size() == ans55.size());
|
|
for (size_t i = 0; i < res55.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res55[i]) == ans55[i]);
|
|
}
|
|
|
|
// oxim/nitroso tautomer via phenol
|
|
std::string smi56 = "O=Nc1ccc(O)cc1";
|
|
std::shared_ptr<ROMol> m56(SmilesToMol(smi56));
|
|
std::vector<ROMOL_SPTR> res56 = te.enumerate(*m56, &tautcat);
|
|
std::vector<std::string> ans56 = {"O=C1C=CC(=NO)C=C1", "O=NC1C=CC(=O)C=C1",
|
|
"O=Nc1ccc(O)cc1"};
|
|
TEST_ASSERT(res56.size() == ans56.size());
|
|
for (size_t i = 0; i < res56.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res56[i]) == ans56[i]);
|
|
}
|
|
|
|
// oxim/nitroso tautomer via phenol
|
|
std::string smi57 = "O=C1C=CC(=NO)C=C1";
|
|
std::shared_ptr<ROMol> m57(SmilesToMol(smi57));
|
|
std::vector<ROMOL_SPTR> res57 = te.enumerate(*m57, &tautcat);
|
|
std::vector<std::string> ans57 = {"O=C1C=CC(=NO)C=C1", "O=NC1C=CC(=O)C=C1",
|
|
"O=Nc1ccc(O)cc1"};
|
|
TEST_ASSERT(res57.size() == ans57.size());
|
|
for (size_t i = 0; i < res57.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res57[i]) == ans57[i]);
|
|
}
|
|
|
|
// cyano/iso-cyanic acid tautomer
|
|
std::string smi58 = "C(#N)O";
|
|
std::shared_ptr<ROMol> m58(SmilesToMol(smi58));
|
|
std::vector<ROMOL_SPTR> res58 = te.enumerate(*m58, &tautcat);
|
|
std::vector<std::string> ans58 = {"N#CO", "N=C=O"};
|
|
TEST_ASSERT(res58.size() == ans58.size());
|
|
for (size_t i = 0; i < res58.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res58[i]) == ans58[i]);
|
|
}
|
|
|
|
// cyano/iso-cyanic acid tautomer
|
|
std::string smi59 = "C(=N)=O";
|
|
std::shared_ptr<ROMol> m59(SmilesToMol(smi59));
|
|
std::vector<ROMOL_SPTR> res59 = te.enumerate(*m59, &tautcat);
|
|
std::vector<std::string> ans59 = {"N#CO", "N=C=O"};
|
|
TEST_ASSERT(res59.size() == ans59.size());
|
|
for (size_t i = 0; i < res59.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res59[i]) == ans59[i]);
|
|
}
|
|
|
|
// isocyanide tautomer
|
|
std::string smi60 = "C#N";
|
|
std::shared_ptr<ROMol> m60(SmilesToMol(smi60));
|
|
std::vector<ROMOL_SPTR> res60 = te.enumerate(*m60, &tautcat);
|
|
std::vector<std::string> ans60 = {"C#N", "[C-]#[NH+]"};
|
|
TEST_ASSERT(res60.size() == ans60.size());
|
|
for (size_t i = 0; i < res60.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res60[i]) == ans60[i]);
|
|
}
|
|
|
|
// isocyanide tautomer
|
|
std::string smi61 = "[C-]#[NH+]";
|
|
std::shared_ptr<ROMol> m61(SmilesToMol(smi61));
|
|
std::vector<ROMOL_SPTR> res61 = te.enumerate(*m61, &tautcat);
|
|
std::vector<std::string> ans61 = {"C#N", "[C-]#[NH+]"};
|
|
TEST_ASSERT(res61.size() == ans61.size());
|
|
for (size_t i = 0; i < res61.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res61[i]) == ans61[i]);
|
|
}
|
|
|
|
// phosphonic acid tautomer
|
|
std::string smi62 = "[PH](=O)(O)(O)";
|
|
std::shared_ptr<ROMol> m62(SmilesToMol(smi62));
|
|
std::vector<ROMOL_SPTR> res62 = te.enumerate(*m62, &tautcat);
|
|
std::vector<std::string> ans62 = {"O=[PH](O)O", "OP(O)O"};
|
|
TEST_ASSERT(res62.size() == ans62.size());
|
|
for (size_t i = 0; i < res62.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res62[i]) == ans62[i]);
|
|
}
|
|
|
|
// phosphonic acid tautomer
|
|
std::string smi63 = "P(O)(O)O";
|
|
std::shared_ptr<ROMol> m63(SmilesToMol(smi63));
|
|
std::vector<ROMOL_SPTR> res63 = te.enumerate(*m63, &tautcat);
|
|
std::vector<std::string> ans63 = {"O=[PH](O)O", "OP(O)O"};
|
|
TEST_ASSERT(res63.size() == ans63.size());
|
|
for (size_t i = 0; i < res63.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res63[i]) == ans63[i]);
|
|
}
|
|
|
|
// Remove stereochemistry from mobile double bonds
|
|
std::string smi64 = "c1(ccccc1)/C=C(/O)\\C";
|
|
std::shared_ptr<ROMol> m64(SmilesToMol(smi64));
|
|
std::vector<ROMOL_SPTR> res64 = te.enumerate(*m64, &tautcat);
|
|
std::vector<std::string> ans64 = {"CC(O)=Cc1ccccc1", "C=C(O)Cc1ccccc1",
|
|
"CC(=O)Cc1ccccc1"};
|
|
TEST_ASSERT(res64.size() == ans64.size());
|
|
for (size_t i = 0; i < res64.size(); ++i) {
|
|
// std::cout << MolToSmiles(*res64[i]) << ", " << ans64[i] << std::endl;
|
|
TEST_ASSERT(MolToSmiles(*res64[i]) == ans64[i]);
|
|
}
|
|
|
|
// Remove stereochemistry from mobile double bonds
|
|
std::string smi65 = "C/C=C/C(C)=O";
|
|
std::shared_ptr<ROMol> m65(SmilesToMol(smi65));
|
|
std::vector<ROMOL_SPTR> res65 = te.enumerate(*m65, &tautcat);
|
|
std::vector<std::string> ans65 = {"CC=CC(C)=O", "C=C(O)C=CC", "C=CC=C(C)O",
|
|
"C=CCC(=C)O", "C=CCC(C)=O"};
|
|
TEST_ASSERT(res65.size() == ans65.size());
|
|
for (size_t i = 0; i < res65.size(); ++i) {
|
|
TEST_ASSERT(MolToSmiles(*res65[i]) == ans65[i]);
|
|
}
|
|
|
|
// Remove stereochemistry from mobile double bonds
|
|
std::string smi66 = "C/C=C\\C(C)=O";
|
|
std::shared_ptr<ROMol> m66(SmilesToMol(smi66));
|
|
std::vector<ROMOL_SPTR> res66 = te.enumerate(*m66, &tautcat);
|
|
std::vector<std::string> ans66 = {"C=C(O)C=CC", "C=CC=C(C)O", "CC=CC(C)=O",
|
|
"C=CCC(=C)O", "C=CCC(C)=O"};
|
|
TEST_ASSERT(res66.size() == ans66.size());
|
|
|
|
std::vector<std::string> sm66;
|
|
for (const auto r : res66) {
|
|
sm66.push_back(MolToSmiles(*r));
|
|
}
|
|
// sort both for alphabetical order
|
|
std::sort(sm66.begin(), sm66.end());
|
|
std::sort(ans66.begin(), ans66.end());
|
|
TEST_ASSERT(sm66 == ans66);
|
|
|
|
// Gaunine tautomers
|
|
std::string smi67 = "N1C(N)=NC=2N=CNC2C1=O";
|
|
std::shared_ptr<ROMol> m67(SmilesToMol(smi67));
|
|
std::vector<ROMOL_SPTR> res67 = te.enumerate(*m67, &tautcat);
|
|
std::vector<std::string> ans67 = {
|
|
"N=c1[nH]c(=O)c2[nH]cnc2[nH]1", "N=c1[nH]c(=O)c2nc[nH]c2[nH]1",
|
|
"N=c1[nH]c2ncnc-2c(O)[nH]1", "N=c1nc(O)c2[nH]cnc2[nH]1",
|
|
"N=c1nc(O)c2nc[nH]c2[nH]1", "N=c1nc2[nH]cnc2c(O)[nH]1",
|
|
"N=c1nc2nc[nH]c2c(O)[nH]1", "Nc1nc(=O)c2[nH]cnc2[nH]1",
|
|
"Nc1nc(=O)c2nc[nH]c2[nH]1", "Nc1nc(O)c2[nH]cnc2n1",
|
|
"Nc1nc(O)c2nc[nH]c2n1", "Nc1nc(O)c2ncnc-2[nH]1",
|
|
"Nc1nc2[nH]cnc2c(=O)[nH]1", "Nc1nc2nc[nH]c2c(=O)[nH]1",
|
|
"Nc1nc2ncnc-2c(O)[nH]1"};
|
|
TEST_ASSERT(res67.size() == ans67.size());
|
|
std::vector<std::string> sm67;
|
|
for (const auto r : res67) {
|
|
sm67.push_back(MolToSmiles(*r));
|
|
}
|
|
// sort both for alphabetical order
|
|
std::sort(sm67.begin(), sm67.end());
|
|
std::sort(ans67.begin(), ans67.end());
|
|
TEST_ASSERT(sm67 == ans67);
|
|
|
|
// Test a structure with hundreds of tautomers.
|
|
std::string smi68 = "[H][C](CO)(NC(=O)C1=C(O)C(O)=CC=C1)C(O)=O";
|
|
std::shared_ptr<ROMol> m68(SmilesToMol(smi68));
|
|
std::vector<ROMOL_SPTR> res68 = te.enumerate(*m68, &tautcat);
|
|
TEST_ASSERT(res68.size() == 375);
|
|
BOOST_LOG(rdInfoLog) << "Finished" << std::endl;
|
|
}
|
|
|
|
void testCanonicalize() {
|
|
std::string rdbase = getenv("RDBASE");
|
|
std::string tautomerFile =
|
|
rdbase + "/Data/MolStandardize/tautomerTransforms.in";
|
|
auto *tautparams = new TautomerCatalogParams(tautomerFile);
|
|
unsigned int ntautomers = tautparams->getNumTautomers();
|
|
TEST_ASSERT(ntautomers == 34);
|
|
|
|
TautomerCatalog tautcat(tautparams);
|
|
// TautomerCanonicalizer tc;
|
|
|
|
// Enumerate 1,3 keto/enol tautomer.
|
|
std::string smi1 = "C1(=CCCCC1)O";
|
|
std::shared_ptr<ROMol> m1(SmilesToMol(smi1));
|
|
// ROMol *res = tc.canonicalize(*m1, &tautcat);
|
|
// TEST_ASSERT(MolToSmiles(*res) == "O=C1CCCCC1");
|
|
}
|
|
|
|
int main() {
|
|
testEnumerator();
|
|
// testCanonicalize();
|
|
return 0;
|
|
}
|