mirror of
https://github.com/rdkit/rdkit.git
synced 2026-06-04 21:54:27 +08:00
* fixes a copy constructor issue:
In copy constructor ‘boost::shared_ptr<T>::shared_ptr(const boost::shared_ptr<T>&) [with T = RDKit::ROMol]’,
inlined from ‘PyObject* RDKit::RunReactant(ChemicalReaction*, T, unsigned int) [with T = boost::python::api::object]’ at /tmp/rdkit_builder/rdkit/Code/GraphMol/ChemReactions/Wrap/rdChemReactions.cpp:129:14:
/usr/include/boost/smart_ptr/shared_ptr.hpp:416:66: warning: ‘*(const boost::shared_ptr<RDKit::ROMol>*)((char*)&<unnamed> + offsetof(boost::python::extract<boost::shared_ptr<RDKit::ROMol> >,boost::python::extract<boost::shared_ptr<RDKit::ROMol> >::<unnamed>.boost::python::converter::extract_rvalue<boost::shared_ptr<RDKit::ROMol> >::m_data.boost::python::converter::rvalue_from_python_data<boost::shared_ptr<RDKit::ROMol> >::<unnamed>.boost::python::converter::rvalue_from_python_storage<boost::shared_ptr<RDKit::ROMol> >::storage)).boost::shared_ptr<RDKit::ROMol>::px’ may be used uninitialized [-Wmaybe-uninitialized]
416 | shared_ptr( shared_ptr const & r ) BOOST_SP_NOEXCEPT : px( r.px ), pn( r.pn )
| ~~^~
/tmp/rdkit_builder/rdkit/Code/GraphMol/ChemReactions/Wrap/rdChemReactions.cpp: In function ‘PyObject* RDKit::RunReactant(ChemicalReaction*, T, unsigned int) [with T = boost::python::api::object]’:
/tmp/rdkit_builder/rdkit/Code/GraphMol/ChemReactions/Wrap/rdChemReactions.cpp:129:30: note: ‘<anonymous>’ declared here
129 | ROMOL_SPTR react = python::extract<ROMOL_SPTR>(reactant);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/boost/smart_ptr/shared_ptr.hpp:17:
In copy constructor ‘boost::detail::shared_count::shared_count(const boost::detail::shared_count&)’,
inlined from ‘boost::shared_ptr<T>::shared_ptr(const boost::shared_ptr<T>&) [with T = RDKit::ROMol]’ at /usr/include/boost/smart_ptr/shared_ptr.hpp:416:72,
inlined from ‘PyObject* RDKit::RunReactant(ChemicalReaction*, T, unsigned int) [with T = boost::python::api::object]’ at /tmp/rdkit_builder/rdkit/Code/GraphMol/ChemReactions/Wrap/rdChemReactions.cpp:129:14:
/usr/include/boost/smart_ptr/detail/shared_count.hpp:438:67: warning: ‘((const boost::detail::shared_count*)((char*)&<unnamed> + offsetof(boost::python::extract<boost::shared_ptr<RDKit::ROMol> >,boost::python::extract<boost::shared_ptr<RDKit::ROMol> >::<unnamed>.boost::python::converter::extract_rvalue<boost::shared_ptr<RDKit::ROMol> >::m_data.boost::python::converter::rvalue_from_python_data<boost::shared_ptr<RDKit::ROMol> >::<unnamed>.boost::python::converter::rvalue_from_python_storage<boost::shared_ptr<RDKit::ROMol> >::storage)))[1].boost::detail::shared_count::pi_’ may be used uninitialized [-Wmaybe-uninitialized]
438 | shared_count(shared_count const & r) BOOST_SP_NOEXCEPT: pi_(r.pi_)
| ~~^~~
/tmp/rdkit_builder/rdkit/Code/GraphMol/ChemReactions/Wrap/rdChemReactions.cpp: In function ‘PyObject* RDKit::RunReactant(ChemicalReaction*, T, unsigned int) [with T = boost::python::api::object]’:
/tmp/rdkit_builder/rdkit/Code/GraphMol/ChemReactions/Wrap/rdChemReactions.cpp:129:30: note: ‘<anonymous>’ declared here
129 | ROMOL_SPTR react = python::extract<ROMOL_SPTR>(reactant);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Fixes a (weird) allocation warning in GCC 12
In file included from /usr/include/c++/12/bits/alloc_traits.h:33,
from /usr/include/c++/12/ext/alloc_traits.h:34,
from /usr/include/c++/12/bits/basic_string.h:39,
from /usr/include/c++/12/string:53,
from /usr/include/c++/12/bits/locale_classes.h:40,
from /usr/include/c++/12/bits/ios_base.h:41,
from /usr/include/c++/12/streambuf:41,
from /usr/include/c++/12/bits/streambuf_iterator.h:35,
from /usr/include/c++/12/iterator:66,
from /usr/include/boost/iterator/iterator_traits.hpp:10,
from /usr/include/boost/range/iterator_range_core.hpp:26,
from /usr/include/boost/range/iterator_range.hpp:13,
from /usr/include/boost/iostreams/traits.hpp:38,
from /usr/include/boost/iostreams/detail/call_traits.hpp:15,
from /usr/include/boost/iostreams/detail/adapter/device_adapter.hpp:22,
from /usr/include/boost/iostreams/tee.hpp:18,
from /tmp/rdkit_builder/rdkit/Code/RDGeneral/RDLog.h:17,
from /tmp/rdkit_builder/rdkit/Code/GraphMol/ChemTransforms/testChemTransforms.cpp:11:
In function ‘void std::_Construct(_Tp*, _Args&& ...) [with _Tp = pair<int, int>; _Args = {const pair<int, int>&}]’,
inlined from ‘_ForwardIterator std::__do_uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = const pair<int, int>*; _ForwardIterator = pair<int, int>*]’ at /usr/include/c++/12/bits/stl_uninitialized.h:120:21,
inlined from ‘static _ForwardIterator std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = const std::pair<int, int>*; _ForwardIterator = std::pair<int, int>*; bool _TrivialValueTypes = false]’ at /usr/include/c++/12/bits/stl_uninitialized.h:137:32,
inlined from ‘_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = const pair<int, int>*; _ForwardIterator = pair<int, int>*]’ at /usr/include/c++/12/bits/stl_uninitialized.h:185:15,
inlined from ‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, allocator<_Tp>&) [with _InputIterator = const pair<int, int>*; _ForwardIterator = pair<int, int>*; _Tp = pair<int, int>]’ at /usr/include/c++/12/bits/stl_uninitialized.h:372:37,
inlined from ‘void std::vector<_Tp, _Alloc>::_M_range_insert(iterator, _ForwardIterator, _ForwardIterator, std::forward_iterator_tag) [with _ForwardIterator = const std::pair<int, int>*; _Tp = std::pair<int, int>; _Alloc = std::allocator<std::pair<int, int> >]’ at /usr/include/c++/12/bits/vector.tcc:808:38,
inlined from ‘std::vector<_Tp, _Alloc>::iterator std::vector<_Tp, _Alloc>::insert(const_iterator, std::initializer_list<_Tp>) [with _Tp = std::pair<int, int>; _Alloc = std::allocator<std::pair<int, int> >]’ at /usr/include/c++/12/bits/stl_vector.h:1409:17,
inlined from ‘void testReplaceCoreMatchVectMultipleMappingToCore()’ at /tmp/rdkit_builder/rdkit/Code/GraphMol/ChemTransforms/testChemTransforms.cpp:974:17:
/usr/include/c++/12/bits/stl_construct.h:119:7: warning: ‘void* __builtin_memcpy(void*, const void*, long unsigned int)’ writing 56 bytes into a region of size 48 overflows the destination [-Wstringop-overflow=]
119 | ::new((void*)__p) _Tp(std::forward<_Args>(__args)...);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/x86_64-linux-gnu/c++/12/bits/c++allocator.h:33,
from /usr/include/c++/12/bits/allocator.h:46,
from /usr/include/c++/12/string:41:
In member function ‘_Tp* std::__new_allocator<_Tp>::allocate(size_type, const void*) [with _Tp = std::pair<int, int>]’,
inlined from ‘static _Tp* std::allocator_traits<std::allocator<_CharT> >::allocate(allocator_type&, size_type) [with _Tp = std::pair<int, int>]’ at /usr/include/c++/12/bits/alloc_traits.h:464:28,
inlined from ‘std::_Vector_base<_Tp, _Alloc>::pointer std::_Vector_base<_Tp, _Alloc>::_M_allocate(std::size_t) [with _Tp = std::pair<int, int>; _Alloc = std::allocator<std::pair<int, int> >]’ at /usr/include/c++/12/bits/stl_vector.h:378:33,
inlined from ‘void std::vector<_Tp, _Alloc>::_M_range_insert(iterator, _ForwardIterator, _ForwardIterator, std::forward_iterator_tag) [with _ForwardIterator = const std::pair<int, int>*; _Tp = std::pair<int, int>; _Alloc = std::allocator<std::pair<int, int> >]’ at /usr/include/c++/12/bits/vector.tcc:799:40,
inlined from ‘std::vector<_Tp, _Alloc>::iterator std::vector<_Tp, _Alloc>::insert(const_iterator, std::initializer_list<_Tp>) [with _Tp = std::pair<int, int>; _Alloc = std::allocator<std::pair<int, int> >]’ at /usr/include/c++/12/bits/stl_vector.h:1409:17,
inlined from ‘void testReplaceCoreMatchVectMultipleMappingToCore()’ at /tmp/rdkit_builder/rdkit/Code/GraphMol/ChemTransforms/testChemTransforms.cpp:974:17:
/usr/include/c++/12/bits/new_allocator.h:137:55: note: at offset [8, 56] into destination object of size 56 allocated by ‘operator new’
137 | return static_cast<_Tp*>(_GLIBCXX_OPERATOR_NEW(__n * sizeof(_Tp)));
| ^
* finalForce maybe uninitialized in inlined copy constructor
* failure is being used uninitialized
* MaeWriter::write overrides a method of the base class without being marked 'override'
This one is annoying because it happens in an exported header, so it propagates
to any code using the header!
* otq is never used
* fix implicitly declared assignment operator warning
* variables in catch statements that are never used
* fix type (sign) mismatch warning
* drop duplicate export macro
285 lines
12 KiB
C++
285 lines
12 KiB
C++
//
|
|
// Copyright (c) 2023, Greg Landrum and other RDKit contributors
|
|
//
|
|
// @@ 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.
|
|
//
|
|
// Tests of the generalized substructure searching code
|
|
//
|
|
|
|
#include "catch.hpp"
|
|
|
|
#include <tuple>
|
|
#include <utility>
|
|
|
|
#include <GraphMol/RDKitBase.h>
|
|
#include <GraphMol/SmilesParse/SmilesParse.h>
|
|
#include <GraphMol/SmilesParse/SmilesWrite.h>
|
|
#include <GraphMol/SmilesParse/SmartsWrite.h>
|
|
#include <GraphMol/GeneralizedSubstruct/XQMol.h>
|
|
#include <GraphMol/TautomerQuery/TautomerQuery.h>
|
|
#include <GraphMol/MolEnumerator/MolEnumerator.h>
|
|
|
|
using namespace RDKit;
|
|
using namespace RDKit::GeneralizedSubstruct;
|
|
|
|
TEST_CASE("molecule basics") {
|
|
auto mol = "Cc1n[nH]c(F)c1"_smarts;
|
|
REQUIRE(mol);
|
|
ExtendedQueryMol xqm = std::make_unique<RWMol>(*mol);
|
|
SECTION("substructure matching and serialization") {
|
|
ExtendedQueryMol xqm2(xqm.toBinary());
|
|
ExtendedQueryMol xqm3(xqm.toJSON(), true);
|
|
for (const auto xq : {&xqm, &xqm2, &xqm3}) {
|
|
CHECK(SubstructMatch(*"CCc1n[nH]c(F)c1"_smiles, *xq).size() == 1);
|
|
CHECK(SubstructMatch(*"CCc1[nH]nc(F)c1"_smiles, *xq).empty());
|
|
CHECK(hasSubstructMatch(*"CCc1n[nH]c(F)c1"_smiles, *xq));
|
|
CHECK(!hasSubstructMatch(*"CCc1[nH]nc(F)c1"_smiles, *xq));
|
|
}
|
|
}
|
|
}
|
|
|
|
TEST_CASE("enumeration basics") {
|
|
auto mol = "COCC |LN:1:1.3|"_smiles;
|
|
REQUIRE(mol);
|
|
ExtendedQueryMol xqm =
|
|
std::make_unique<MolBundle>(MolEnumerator::enumerate(*mol));
|
|
SECTION("substructure matching and serialization") {
|
|
ExtendedQueryMol xqm2(xqm.toBinary());
|
|
ExtendedQueryMol xqm3(xqm.toJSON(), true);
|
|
|
|
for (const auto xq : {&xqm, &xqm2, &xqm3}) {
|
|
CHECK(SubstructMatch(*"COCC"_smiles, *xq).size() == 1);
|
|
CHECK(SubstructMatch(*"COOCC"_smiles, *xq).size() == 1);
|
|
CHECK(SubstructMatch(*"COOOCC"_smiles, *xq).size() == 1);
|
|
CHECK(SubstructMatch(*"COOOOCC"_smiles, *xq).empty());
|
|
}
|
|
}
|
|
}
|
|
|
|
TEST_CASE("result counts") {
|
|
auto mol = "COC |LN:1:1.3|"_smiles;
|
|
REQUIRE(mol);
|
|
ExtendedQueryMol xqm =
|
|
std::make_unique<MolBundle>(MolEnumerator::enumerate(*mol));
|
|
SECTION("substructure matching and serialization") {
|
|
ExtendedQueryMol xqm2(xqm.toBinary());
|
|
ExtendedQueryMol xqm3(xqm.toJSON(), true);
|
|
SubstructMatchParameters ps;
|
|
ps.uniquify = false;
|
|
for (const auto xq : {&xqm, &xqm2, &xqm3}) {
|
|
CHECK(SubstructMatch(*"COCC"_smiles, *xq, ps).size() == 2);
|
|
CHECK(SubstructMatch(*"COOCC"_smiles, *xq, ps).size() == 2);
|
|
CHECK(SubstructMatch(*"COOOCC"_smiles, *xq, ps).size() == 2);
|
|
CHECK(SubstructMatch(*"COOOOCC"_smiles, *xq, ps).empty());
|
|
}
|
|
}
|
|
}
|
|
|
|
TEST_CASE("tautomer basics") {
|
|
auto mol = "Cc1n[nH]c(F)c1"_smiles;
|
|
REQUIRE(mol);
|
|
ExtendedQueryMol xqm =
|
|
std::unique_ptr<TautomerQuery>(TautomerQuery::fromMol(*mol));
|
|
|
|
SECTION("substructure matching and serialization") {
|
|
ExtendedQueryMol xqm2(xqm.toBinary());
|
|
ExtendedQueryMol xqm3(xqm.toJSON(), true);
|
|
for (const auto xq : {&xqm, &xqm2, &xqm3}) {
|
|
CHECK(SubstructMatch(*"CCc1n[nH]c(F)c1"_smiles, *xq).size() == 1);
|
|
CHECK(SubstructMatch(*"CCc1[nH]nc(F)c1"_smiles, *xq).size() == 1);
|
|
CHECK(SubstructMatch(*"CCc1[nH]ncc1"_smiles, *xq).empty());
|
|
}
|
|
}
|
|
}
|
|
|
|
TEST_CASE("tautomer bundle basics") {
|
|
auto mol1 = "Cc1n[nH]c(F)c1"_smiles;
|
|
REQUIRE(mol1);
|
|
auto mol2 = "Cc1n[nH]cc1F"_smiles;
|
|
REQUIRE(mol2);
|
|
std::vector<std::unique_ptr<TautomerQuery>> tbndl;
|
|
tbndl.emplace_back(
|
|
std::unique_ptr<TautomerQuery>(TautomerQuery::fromMol(*mol1)));
|
|
tbndl.emplace_back(
|
|
std::unique_ptr<TautomerQuery>(TautomerQuery::fromMol(*mol2)));
|
|
ExtendedQueryMol xqm =
|
|
std::make_unique<std::vector<std::unique_ptr<TautomerQuery>>>(
|
|
std::move(tbndl));
|
|
SECTION("substructure matching and serialization") {
|
|
ExtendedQueryMol xqm2(xqm.toBinary());
|
|
ExtendedQueryMol xqm3(xqm.toJSON(), true);
|
|
for (const auto xq : {&xqm, &xqm2, &xqm3}) {
|
|
CHECK(SubstructMatch(*"CCc1n[nH]c(F)c1"_smiles, *xq).size() == 1);
|
|
CHECK(SubstructMatch(*"CCc1[nH]nc(F)c1"_smiles, *xq).size() == 1);
|
|
CHECK(SubstructMatch(*"CCc1[nH]ncc1F"_smiles, *xq).size() == 1);
|
|
CHECK(SubstructMatch(*"CCc1n[nH]cc1F"_smiles, *xq).size() == 1);
|
|
CHECK(SubstructMatch(*"CCc1[nH]ncc1"_smiles, *xq).empty());
|
|
}
|
|
}
|
|
}
|
|
|
|
TEST_CASE("createExtendedQueryMol") {
|
|
SECTION("RWMol") {
|
|
auto mol = "COCC"_smiles;
|
|
REQUIRE(mol);
|
|
auto xqm = createExtendedQueryMol(*mol);
|
|
CHECK(std::holds_alternative<ExtendedQueryMol::RWMol_T>(xqm.xqmol));
|
|
CHECK(SubstructMatch(*"COCC"_smiles, xqm).size() == 1);
|
|
CHECK(SubstructMatch(*"COOCC"_smiles, xqm).empty());
|
|
}
|
|
SECTION("MolBundle") {
|
|
auto mol = "COCC |LN:1:1.3|"_smiles;
|
|
REQUIRE(mol);
|
|
auto xqm = createExtendedQueryMol(*mol);
|
|
CHECK(std::holds_alternative<ExtendedQueryMol::MolBundle_T>(xqm.xqmol));
|
|
CHECK(SubstructMatch(*"COCC"_smiles, xqm).size() == 1);
|
|
CHECK(SubstructMatch(*"COOCC"_smiles, xqm).size() == 1);
|
|
CHECK(SubstructMatch(*"COOOCC"_smiles, xqm).size() == 1);
|
|
CHECK(SubstructMatch(*"COOOOCC"_smiles, xqm).empty());
|
|
}
|
|
SECTION("TautomerQuery") {
|
|
auto mol1 = "CC1OC(N)=N1"_smiles;
|
|
REQUIRE(mol1);
|
|
auto xqm = createExtendedQueryMol(*mol1);
|
|
CHECK(std::holds_alternative<ExtendedQueryMol::TautomerQuery_T>(xqm.xqmol));
|
|
CHECK(SubstructMatch(*"CCC1OC(N)=N1"_smiles, xqm).size() == 1);
|
|
CHECK(SubstructMatch(*"CCC1OC(=N)N1"_smiles, *mol1).empty());
|
|
CHECK(SubstructMatch(*"CCC1OC(=N)N1"_smiles, xqm).size() == 1);
|
|
CHECK(SubstructMatch(*"c1[nH]ncc1"_smiles, xqm).empty());
|
|
}
|
|
SECTION("TautomerBundle") {
|
|
auto mol1 = "COCC1OC(N)=N1 |LN:1:1.3|"_smiles;
|
|
REQUIRE(mol1);
|
|
auto xqm = createExtendedQueryMol(*mol1);
|
|
CHECK(
|
|
std::holds_alternative<ExtendedQueryMol::TautomerBundle_T>(xqm.xqmol));
|
|
CHECK(SubstructMatch(*"COCC1(F)OC(N)=N1"_smiles, xqm).size() == 1);
|
|
CHECK(SubstructMatch(*"COOCC1(F)OC(=N)N1"_smiles, xqm).size() == 1);
|
|
CHECK(SubstructMatch(*"COCC1OC(N)=N1"_smiles, xqm).size() == 1);
|
|
CHECK(SubstructMatch(*"COOOOCC1OC(=N)N1"_smiles, xqm).empty());
|
|
}
|
|
}
|
|
|
|
TEST_CASE("test SRUs") {
|
|
SECTION("basics") {
|
|
auto mol = "FCN(CC)-* |Sg:n:2,5:1-2:ht|"_smiles;
|
|
REQUIRE(mol);
|
|
auto xqm = createExtendedQueryMol(*mol);
|
|
CHECK(std::holds_alternative<ExtendedQueryMol::MolBundle_T>(xqm.xqmol));
|
|
// as of v2023.03.1 the SRU enumerator ignores repeat counts, so
|
|
// we won't test limits here.
|
|
CHECK(SubstructMatch(*"FCN(C)CC"_smiles, xqm).size() == 1);
|
|
CHECK(SubstructMatch(*"FCN(O)N(C)CC"_smiles, xqm).size() == 1);
|
|
}
|
|
}
|
|
|
|
// there's some redundancy in testing with what's above, but duplicating tests
|
|
// isn't a terrible thing
|
|
TEST_CASE("adjustQueryProperties") {
|
|
bool doEnumeration = true;
|
|
bool doTautomers = true;
|
|
bool adjustQueryProperties = true;
|
|
SECTION("RWMol") {
|
|
auto mol = "COC1CC1"_smiles;
|
|
REQUIRE(mol);
|
|
auto xqm1 = createExtendedQueryMol(*mol, doEnumeration, doTautomers);
|
|
auto xqm2 = createExtendedQueryMol(*mol, doEnumeration, doTautomers,
|
|
adjustQueryProperties);
|
|
MolOps::AdjustQueryParameters aqps =
|
|
MolOps::AdjustQueryParameters::noAdjustments();
|
|
aqps.makeAtomsGeneric = true;
|
|
auto xqm3 = createExtendedQueryMol(*mol, doEnumeration, doTautomers,
|
|
adjustQueryProperties, aqps);
|
|
CHECK(std::holds_alternative<ExtendedQueryMol::RWMol_T>(xqm1.xqmol));
|
|
CHECK(std::holds_alternative<ExtendedQueryMol::RWMol_T>(xqm2.xqmol));
|
|
CHECK(std::holds_alternative<ExtendedQueryMol::RWMol_T>(xqm3.xqmol));
|
|
CHECK(SubstructMatch(*"COC1CC1"_smiles, xqm1).size() == 1);
|
|
CHECK(SubstructMatch(*"COC1CC1"_smiles, xqm2).size() == 1);
|
|
CHECK(SubstructMatch(*"COC1CC1"_smiles, xqm3).size() == 1);
|
|
CHECK(SubstructMatch(*"COC1C(C)C1"_smiles, xqm1).size() == 1);
|
|
CHECK(SubstructMatch(*"COC1C(C)C1"_smiles, xqm2).empty());
|
|
CHECK(SubstructMatch(*"COC1C(C)C1"_smiles, xqm3).size() == 1);
|
|
CHECK(SubstructMatch(*"COC1OC1"_smiles, xqm1).empty());
|
|
CHECK(SubstructMatch(*"COC1OC1"_smiles, xqm2).empty());
|
|
CHECK(SubstructMatch(*"COC1OC1"_smiles, xqm3).size() == 1);
|
|
}
|
|
SECTION("MolBundle") {
|
|
auto mol = "COCC |LN:1:1.3|"_smiles;
|
|
REQUIRE(mol);
|
|
auto xqm1 = createExtendedQueryMol(*mol, doEnumeration, doTautomers);
|
|
MolOps::AdjustQueryParameters aqps =
|
|
MolOps::AdjustQueryParameters::noAdjustments();
|
|
aqps.makeBondsGeneric = true;
|
|
auto xqm2 = createExtendedQueryMol(*mol, doEnumeration, doTautomers,
|
|
adjustQueryProperties, aqps);
|
|
CHECK(std::holds_alternative<ExtendedQueryMol::MolBundle_T>(xqm1.xqmol));
|
|
CHECK(std::holds_alternative<ExtendedQueryMol::MolBundle_T>(xqm2.xqmol));
|
|
CHECK(SubstructMatch(*"COC=C"_smiles, xqm1).empty());
|
|
CHECK(SubstructMatch(*"COOC=C"_smiles, xqm1).empty());
|
|
CHECK(SubstructMatch(*"COC=C"_smiles, xqm2).size() == 1);
|
|
CHECK(SubstructMatch(*"COOC=C"_smiles, xqm2).size() == 1);
|
|
}
|
|
SECTION("TautomerQuery") {
|
|
auto mol1 = "CC1OC(N)=N1"_smiles;
|
|
REQUIRE(mol1);
|
|
auto xqm1 = createExtendedQueryMol(*mol1, doEnumeration, doTautomers);
|
|
auto xqm2 = createExtendedQueryMol(*mol1, doEnumeration, doTautomers,
|
|
adjustQueryProperties);
|
|
|
|
CHECK(
|
|
std::holds_alternative<ExtendedQueryMol::TautomerQuery_T>(xqm1.xqmol));
|
|
CHECK(
|
|
std::holds_alternative<ExtendedQueryMol::TautomerQuery_T>(xqm2.xqmol));
|
|
CHECK(SubstructMatch(*"CC1OC(N)=N1"_smiles, xqm1).size() == 1);
|
|
CHECK(SubstructMatch(*"CC1OC(N)=N1"_smiles, xqm2).size() == 1);
|
|
CHECK(SubstructMatch(*"CC1(F)OC(N)=N1"_smiles, xqm1).size() == 1);
|
|
CHECK(SubstructMatch(*"CC1(F)OC(=N)N1"_smiles, xqm1).size() == 1);
|
|
CHECK(SubstructMatch(*"CC1(F)OC(N)=N1"_smiles, xqm2).empty());
|
|
CHECK(SubstructMatch(*"CC1(F)OC(=N)N1"_smiles, xqm2).empty());
|
|
}
|
|
SECTION("TautomerBundle") {
|
|
auto mol1 = "COCC1OC(N)=N1 |LN:1:1.3|"_smiles;
|
|
REQUIRE(mol1);
|
|
auto xqm1 = createExtendedQueryMol(*mol1, doEnumeration, doTautomers);
|
|
auto xqm2 = createExtendedQueryMol(*mol1, doEnumeration, doTautomers,
|
|
adjustQueryProperties);
|
|
CHECK(
|
|
std::holds_alternative<ExtendedQueryMol::TautomerBundle_T>(xqm1.xqmol));
|
|
CHECK(SubstructMatch(*"COCC1OC(N)=N1"_smiles, xqm1).size() == 1);
|
|
CHECK(SubstructMatch(*"COOCC1OC(=N)N1"_smiles, xqm1).size() == 1);
|
|
CHECK(SubstructMatch(*"COCC1OC(N)=N1"_smiles, xqm2).size() == 1);
|
|
CHECK(SubstructMatch(*"COOCC1OC(=N)N1"_smiles, xqm2).size() == 1);
|
|
CHECK(SubstructMatch(*"COCC1(F)OC(N)=N1"_smiles, xqm1).size() == 1);
|
|
CHECK(SubstructMatch(*"COOCC1(F)OC(=N)N1"_smiles, xqm1).size() == 1);
|
|
CHECK(SubstructMatch(*"COCC1(F)OC(N)=N1"_smiles, xqm2).empty());
|
|
CHECK(SubstructMatch(*"COOCC1(F)OC(=N)N1"_smiles, xqm2).empty());
|
|
}
|
|
}
|
|
|
|
TEST_CASE("controlling which steps are applied") {
|
|
auto mol1 = "COCC1OC(N)=N1 |LN:1:1.3|"_smiles;
|
|
bool doEnumeration = true;
|
|
bool doTautomers = true;
|
|
REQUIRE(mol1);
|
|
{
|
|
auto xqm = createExtendedQueryMol(*mol1, doEnumeration, doTautomers);
|
|
CHECK(
|
|
std::holds_alternative<ExtendedQueryMol::TautomerBundle_T>(xqm.xqmol));
|
|
}
|
|
{
|
|
auto xqm = createExtendedQueryMol(*mol1, doEnumeration, false);
|
|
CHECK(std::holds_alternative<ExtendedQueryMol::MolBundle_T>(xqm.xqmol));
|
|
}
|
|
{
|
|
auto xqm = createExtendedQueryMol(*mol1, false, doTautomers);
|
|
CHECK(std::holds_alternative<ExtendedQueryMol::TautomerQuery_T>(xqm.xqmol));
|
|
}
|
|
{
|
|
auto xqm = createExtendedQueryMol(*mol1, false, false);
|
|
CHECK(std::holds_alternative<ExtendedQueryMol::RWMol_T>(xqm.xqmol));
|
|
}
|
|
} |