* stop finding potential nontetrahedral sites when nontetrahedral stereo is disabled
stop matching [PH3] as potential stereo

* add another test
This commit is contained in:
Greg Landrum
2023-01-26 19:26:19 +01:00
committed by GitHub
parent 0570d3e44f
commit ec67021fa0
2 changed files with 57 additions and 7 deletions

View File

@@ -28,8 +28,9 @@ namespace detail {
bool isAtomPotentialNontetrahedralCenter(const Atom *atom) {
PRECONDITION(atom, "atom is null");
auto tnzdegree =
Chirality::detail::getAtomNonzeroDegree(atom) + atom->getTotalNumHs();
auto nzdegree = Chirality::detail::getAtomNonzeroDegree(atom);
auto impHDegree = atom->getTotalNumHs();
auto tnzdegree = nzdegree + impHDegree;
auto anum = atom->getAtomicNum();
if (tnzdegree > 6 || tnzdegree < 2 || (anum < 12 && anum != 4)) {
return false;
@@ -59,8 +60,8 @@ bool isAtomPotentialTetrahedralCenter(const Atom *atom) {
if (nzDegree == 4) {
// chirality is always possible with 4 nbrs
return true;
} else if (nzDegree == 1) {
// chirality is never possible with 1 nbr
} else if (nzDegree <= 1) {
// chirality is never possible with 0 or 1 nbr
return false;
} else if (nzDegree < 3 &&
(atom->getAtomicNum() != 15 && atom->getAtomicNum() != 33)) {
@@ -106,9 +107,15 @@ bool isAtomPotentialTetrahedralCenter(const Atom *atom) {
}
}
bool isAtomPotentialStereoAtom(const Atom *atom) {
bool isAtomPotentialStereoAtom(const Atom *atom,
bool allowNontetrahehdralStereo) {
return isAtomPotentialTetrahedralCenter(atom) ||
isAtomPotentialNontetrahedralCenter(atom);
(allowNontetrahehdralStereo &&
isAtomPotentialNontetrahedralCenter(atom));
}
bool isAtomPotentialStereoAtom(const Atom *atom) {
return isAtomPotentialStereoAtom(atom, getAllowNontetrahedralChirality());
}
StereoInfo getStereoInfo(const Bond *bond) {
@@ -452,10 +459,11 @@ void initAtomInfo(ROMol &mol, bool flagPossible, bool cleanIt,
boost::dynamic_bitset<> &knownAtoms,
std::vector<std::string> &atomSymbols,
boost::dynamic_bitset<> &possibleAtoms) {
bool allowNontetrahedralStereo = getAllowNontetrahedralChirality();
for (const auto atom : mol.atoms()) {
auto aidx = atom->getIdx();
atomSymbols[aidx] = getAtomCompareSymbol(*atom);
if (detail::isAtomPotentialStereoAtom(atom)) {
if (detail::isAtomPotentialStereoAtom(atom, allowNontetrahedralStereo)) {
auto sinfo = detail::getStereoInfo(atom);
switch (sinfo.specified) {
case Chirality::StereoSpecified::Unknown:

View File

@@ -3253,3 +3253,45 @@ TEST_CASE("double bond stereo with new chirality perception") {
}
}
}
TEST_CASE("false positives from new stereo code") {
SECTION("elements") {
std::vector<std::string> examples{"P", "PC", "S", "SC", "S(F)C"};
for (auto &smi : examples) {
INFO(smi);
std::unique_ptr<RWMol> m{SmilesToMol(smi)};
REQUIRE(m);
auto si = Chirality::findPotentialStereo(*m);
CHECK(si.empty());
}
}
SECTION("non-tetrahedral and implicit Hs") {
std::vector<std::string> examples{
"[SiH4]", "[SiH3]C", "[SH4]", "[PH5]",
"[PH4]C", "[SH6]", "[SH5]C", "[SiH2](C)C",
"[PH3](C)C", "[PH2](C)(C)C", "[SH4](C)C", "[SH3](C)(C)C",
"[SH2](C)(C)(C)C"};
{
AllowNontetrahedralChiralityFixture reset_non_tetrahedral_allowed;
Chirality::setAllowNontetrahedralChirality(false);
for (auto &smi : examples) {
INFO(smi);
std::unique_ptr<RWMol> m{SmilesToMol(smi)};
REQUIRE(m);
auto si = Chirality::findPotentialStereo(*m);
CHECK(si.empty());
}
}
{
AllowNontetrahedralChiralityFixture reset_non_tetrahedral_allowed;
Chirality::setAllowNontetrahedralChirality(true);
for (auto &smi : examples) {
INFO(smi);
std::unique_ptr<RWMol> m{SmilesToMol(smi)};
REQUIRE(m);
auto si = Chirality::findPotentialStereo(*m);
CHECK(si.size() == 1);
}
}
}
}