mirror of
https://github.com/rdkit/rdkit.git
synced 2026-06-03 21:44:30 +08:00
committed by
Brian Kelley
parent
2b98b36184
commit
3ce2016039
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user