Skip to content

Commit

Permalink
Fix Uncharger applying to already neutralized perhalic groups (#7211)
Browse files Browse the repository at this point in the history
  • Loading branch information
rvianello authored and greglandrum committed Mar 7, 2024
1 parent 663c220 commit 1c2f3f6
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 8 deletions.
18 changes: 10 additions & 8 deletions Code/GraphMol/MolStandardize/Charge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ void Uncharger::unchargeInPlace(RWMol &mol) {
// insert the elements from a_atoms, but make sure that
// the anions of monoprotic acids are not protonated multiple
// times
boost::dynamic_bitset<> skipChargeSep(mol.getNumAtoms());
std::vector<int> skipChargeSep(mol.getNumAtoms());
for (const auto &pair : a_atoms) {
unsigned int idx = pair.second;
Atom *atom = mol.getAtomWithIdx(idx);
Expand All @@ -415,20 +415,22 @@ void Uncharger::unchargeInPlace(RWMol &mol) {
const auto &nbr = (mol)[nbri];
auto nbrIdx = nbr->getIdx();
// if the neighbor has a positive charge,
// neutralize only once (e.g., NO3-)
if (nbr->getFormalCharge() > 0) {
if (!skipChargeSep.test(nbrIdx)) {
skipChargeSep.set(nbrIdx);
} else {
skipChargeSep.set(idx);
// neutralize only the negative charges that are not
// already balanced within the functional group
// (normally, at most once e.g., NO3-)
auto nbrFormalCharge = nbr->getFormalCharge();
if (nbrFormalCharge > 0) {
if (skipChargeSep[nbrIdx] < nbrFormalCharge) {
skipChargeSep[nbrIdx] += 1;
skipChargeSep[idx] = 1;
}
break;
}
}
}
for (const auto &pair : a_atoms) {
unsigned int idx = pair.second;
if (skipChargeSep.test(idx)) {
if (skipChargeSep[idx]) {
continue;
}
neg_atoms.push_back(pair);
Expand Down
6 changes: 6 additions & 0 deletions Code/GraphMol/MolStandardize/testCharge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,12 @@ void testInorganicAcids() {
TEST_ASSERT(perhalate);
res.reset(uncharger.uncharge(*perhalate));
TEST_ASSERT(MolToSmiles(*res) == "[O-][" + halogen + "+3]([O-])([O-])O");
// also test uncharging the already neutralized acid
std::unique_ptr<ROMol> perhalic_acid(
SmilesToMol("[" + halogen + "](=O)(=O)(=O)O"));
TEST_ASSERT(perhalic_acid);
res.reset(uncharger.uncharge(*perhalic_acid));
TEST_ASSERT(MolToSmiles(*res) == "[O-][" + halogen + "+3]([O-])([O-])O");
}
{
auto hyponitrite = "[O-]N=N[O-]"_smiles;
Expand Down

0 comments on commit 1c2f3f6

Please sign in to comment.