This commit is contained in:
Greg Landrum
2019-06-25 05:07:19 +02:00
committed by Brian Kelley
parent 2b98b36184
commit 3ce2016039
4 changed files with 64 additions and 14 deletions

View File

@@ -22,12 +22,12 @@
#include <RDGeneral/Dict.h>
namespace RDKit {
namespace {
// Determine whether or not a molecule is to the left of Carbon
bool isEarlyAtom(int atomicNum) {
return (4 - PeriodicTable::getTable()->getNouterElecs(atomicNum)) > 0;
}
} // namespace
Atom::Atom() : RDProps() {
d_atomicNum = 0;
initAtom();

View File

@@ -433,4 +433,8 @@ RDKIT_GRAPHMOL_EXPORT std::string getSupplementalSmilesLabel(const Atom *atom);
RDKIT_GRAPHMOL_EXPORT std::ostream &operator<<(std::ostream &target,
const RDKit::Atom &at);
namespace RDKit {
//! returns whether or not the atom is to the left of C
RDKIT_GRAPHMOL_EXPORT bool isEarlyAtom(int atomicNum);
} // namespace RDKit
#endif

View File

@@ -318,13 +318,23 @@ ROMol *Uncharger::uncharge(const ROMol &mol) {
unsigned int idx = n_atoms[midx++].second;
if (!nonAcids[idx]) continue;
Atom *atom = omol->getAtomWithIdx(idx);
// Add hydrogen to first negative acid atom, increase formal charge
// Until quaternary positive == negative total or no more negative acid
atom->setNoImplicit(true);
atom->setNumExplicitHs(atom->getNumExplicitHs() + 1);
atom->setFormalCharge(atom->getFormalCharge() + 1);
--neg_surplus;
BOOST_LOG(rdInfoLog) << "Removed negative charge.\n";
if (!isEarlyAtom(atom->getAtomicNum())) {
// Add hydrogen to negative atom, increase formal charge
// Until quaternary positive == negative total or no more negative
// acid
atom->setNoImplicit(true);
atom->setNumExplicitHs(atom->getNumExplicitHs() + 1);
atom->setFormalCharge(atom->getFormalCharge() + 1);
--neg_surplus;
BOOST_LOG(rdInfoLog) << "Removed negative charge.\n";
} else if (atom->getNumExplicitHs()) {
atom->setNoImplicit(true);
atom->setNumExplicitHs(atom->getNumExplicitHs() - 1);
atom->setFormalCharge(atom->getFormalCharge() + 1);
--neg_surplus;
BOOST_LOG(rdInfoLog) << "Removed negative charge.\n";
}
}
}
@@ -350,11 +360,20 @@ ROMol *Uncharger::uncharge(const ROMol &mol) {
for (const auto &pair : n_atoms) {
auto idx = pair.second;
Atom *atom = omol->getAtomWithIdx(idx);
atom->setNoImplicit(true);
while (atom->getFormalCharge() < 0) {
atom->setNumExplicitHs(atom->getNumExplicitHs() + 1);
atom->setFormalCharge(atom->getFormalCharge() + 1);
BOOST_LOG(rdInfoLog) << "Removed negative charge.\n";
if (!isEarlyAtom(atom->getAtomicNum())) {
atom->setNoImplicit(true);
while (atom->getFormalCharge() < 0) {
atom->setNumExplicitHs(atom->getNumExplicitHs() + 1);
atom->setFormalCharge(atom->getFormalCharge() + 1);
BOOST_LOG(rdInfoLog) << "Removed negative charge.\n";
}
} else if (atom->getNumExplicitHs()) {
atom->setNoImplicit(true);
while (atom->getFormalCharge() < 0 && atom->getNumExplicitHs()) {
atom->setNumExplicitHs(atom->getNumExplicitHs() - 1);
atom->setFormalCharge(atom->getFormalCharge() + 1);
BOOST_LOG(rdInfoLog) << "Removed negative charge.\n";
}
}
}
}

View File

@@ -143,4 +143,31 @@ TEST_CASE(
REQUIRE(outm);
CHECK(MolToSmiles(*outm) == "CN(C)(C)C");
}
}
TEST_CASE(
"github #2452: incorrectly removing charge from boron anions"
"fragments ") {
SECTION("demo") {
auto m = "C[B-](C)(C)C"_smiles;
REQUIRE(m);
bool canonicalOrdering = true;
MolStandardize::Uncharger uncharger(canonicalOrdering);
std::unique_ptr<ROMol> outm(uncharger.uncharge(*m));
REQUIRE(outm);
CHECK(outm->getAtomWithIdx(1)->getFormalCharge() == -1);
CHECK(MolToSmiles(*outm) == "C[B-](C)(C)C");
}
SECTION("should be removed") {
auto m = "C[BH-](C)(C)"_smiles;
REQUIRE(m);
bool canonicalOrdering = true;
MolStandardize::Uncharger uncharger(canonicalOrdering);
std::unique_ptr<ROMol> outm(uncharger.uncharge(*m));
REQUIRE(outm);
CHECK(outm->getAtomWithIdx(1)->getFormalCharge() == 0);
CHECK(MolToSmiles(*outm) == "CB(C)C");
}
}