Allow labeled atoms to have working queries (#8849)

* Allow labeled atoms to have working queries

* Remove stray keystrokes

* Fix typo

* Apply clang-format

* Move simpler checks first

---------

Co-authored-by: Brian Kelley <bkelley@glysade.com>
This commit is contained in:
Brian Kelley
2025-10-08 22:46:20 -04:00
committed by GitHub
parent 686ca3fd6e
commit b0ef80d68d
2 changed files with 48 additions and 1 deletions

View File

@@ -418,6 +418,23 @@ void RCore::buildMatchingMol() {
// then keep one attachment
if (atom->getAtomicNum() == 0 && atom->getDegree() == 1 &&
isDummyRGroupAttachment(*atom)) {
// if we are a query in disguise, don't strip
if (atom->hasQuery()) {
auto q = atom->getQuery()->getDescription();
// If we are anything but AtomNull or AtomAtomicNum we are not
// fully a dummy atom
if (q != "AtomNull" && q != "AtomAtomicNum") {
unsigned int type = 0xFFFFFFFF;
// If we are were set as an RLABEL of type Isotope we probably
// have a query of named "AtomIsotope"
// we DO strip these unless they have an additional query
if (q != "AtomIsotope" || !atom->getPropIfPresent(RLABEL_TYPE, type) ||
type != RGroupLabels::IsotopeLabels) {
continue;
}
}
}
// remove terminal user R groups and map the index of the core neighbor
// atom to the index of the removed terminal R group
const int neighborIdx = *matchingMol->getAtomNeighbors(atom).first;

View File

@@ -4146,13 +4146,42 @@ void testRgroupDecompZipping() {
}
}
void testSmartsOnDummyAtoms() {
BOOST_LOG(rdInfoLog)
<< "********************************************************\n";
BOOST_LOG(rdInfoLog)
<< "Test we can reconstruct rgroup decomps that break rings" << std::endl;
const auto core = "[$([1C]):1]C[$([2C]):2]"_smarts;
const auto mol1 = "N[1C]C[2C]"_smiles;
const auto mol2 = "N[2C]C[1C]"_smiles;
const std::vector<std::string> expected = {
"Core:C([*:1])[*:2] R1:N[1C][*:1] R2:[2C][*:2]",
"Core:C([*:1])[*:2] R1:[1C][*:1] R2:N[2C][*:2]"
};
RGroupDecomposition decomp(*core);
auto add11 = decomp.add(*mol1);
TEST_ASSERT(add11 == 0);
add11 = decomp.add(*mol2);
TEST_ASSERT(add11 == 1)
decomp.process();
RGroupRows rows = decomp.getRGroupsAsRows();
int i = 0;
for (RGroupRows::const_iterator it = rows.begin(); it != rows.end();
++it, ++i) {
CHECK_RGROUP(it, expected[i]);
}
}
int main() {
RDLog::InitLogs();
boost::logging::disable_logs("rdApp.debug");
BOOST_LOG(rdInfoLog)
<< "********************************************************\n";
BOOST_LOG(rdInfoLog) << "Testing R-Group Decomposition \n";
testSymmetryMatching(FingerprintVariance);
testSymmetryMatching();
testRGroupOnlyMatching();
@@ -4210,6 +4239,7 @@ int main() {
testStereoBondBug();
testNotEnumeratedCore();
testRgroupDecompZipping();
testSmartsOnDummyAtoms();
BOOST_LOG(rdInfoLog)
<< "********************************************************\n";
return 0;