add ROMol::atomNeighbors() and ROMol::atomBonds() (#4573)

* add ROMol::atomBonds() and ROMol::atomNeighbors() methods

* remove some warnings

* start using the new code

* add default for those template params

* some more applications

* get the SWIG builds working

* get rid of extraneous ref

* remove extraneous comments
This commit is contained in:
Greg Landrum
2021-10-02 07:28:24 +02:00
committed by GitHub
parent 3720537c7e
commit 85608555fe
18 changed files with 230 additions and 225 deletions

View File

@@ -74,31 +74,26 @@ void nitrogenCleanup(RWMol &mol, Atom *atom) {
// the sanitization process):
if (atom->calcExplicitValence(false) == 5) {
unsigned int aid = atom->getIdx();
RWMol::ADJ_ITER nid1, end1;
boost::tie(nid1, end1) = mol.getAtomNeighbors(atom);
while (nid1 != end1) {
if ((mol.getAtomWithIdx(*nid1)->getAtomicNum() == 8) &&
(mol.getAtomWithIdx(*nid1)->getFormalCharge() == 0) &&
(mol.getBondBetweenAtoms(aid, *nid1)->getBondType() ==
for (const auto nbr : mol.atomNeighbors(atom)) {
if ((nbr->getAtomicNum() == 8) && (nbr->getFormalCharge() == 0) &&
(mol.getBondBetweenAtoms(aid, nbr->getIdx())->getBondType() ==
Bond::DOUBLE)) {
// here's the double bonded oxygen
Bond *b = mol.getBondBetweenAtoms(aid, *nid1);
auto b = mol.getBondBetweenAtoms(aid, nbr->getIdx());
b->setBondType(Bond::SINGLE);
atom->setFormalCharge(1);
mol.getAtomWithIdx(*nid1)->setFormalCharge(-1);
nbr->setFormalCharge(-1);
break;
} else if ((mol.getAtomWithIdx(*nid1)->getAtomicNum() == 7) &&
(mol.getAtomWithIdx(*nid1)->getFormalCharge() == 0) &&
(mol.getBondBetweenAtoms(aid, *nid1)->getBondType() ==
} else if ((nbr->getAtomicNum() == 7) && (nbr->getFormalCharge() == 0) &&
(mol.getBondBetweenAtoms(aid, nbr->getIdx())->getBondType() ==
Bond::TRIPLE)) {
// here's the triple bonded nitrogen
Bond *b = mol.getBondBetweenAtoms(aid, *nid1);
auto b = mol.getBondBetweenAtoms(aid, nbr->getIdx());
b->setBondType(Bond::DOUBLE);
atom->setFormalCharge(1);
mol.getAtomWithIdx(*nid1)->setFormalCharge(-1);
nbr->setFormalCharge(-1);
break;
}
++nid1;
} // end of loop over the first neigh
} // if this atom is 5 coordinate nitrogen
// force a recalculation of the explicit valence here
@@ -127,24 +122,19 @@ void phosphorusCleanup(RWMol &mol, Atom *atom) {
Bond *dbl_to_O = nullptr;
Atom *O_atom = nullptr;
bool hasDoubleToCorN = false;
RWMol::ADJ_ITER nid1, end1;
boost::tie(nid1, end1) = mol.getAtomNeighbors(atom);
while (nid1 != end1) {
if ((mol.getAtomWithIdx(*nid1)->getAtomicNum() == 8) &&
(mol.getAtomWithIdx(*nid1)->getFormalCharge() == 0) &&
(mol.getBondBetweenAtoms(aid, *nid1)->getBondType() ==
for (const auto nbr : mol.atomNeighbors(atom)) {
if ((nbr->getAtomicNum() == 8) && (nbr->getFormalCharge() == 0) &&
(mol.getBondBetweenAtoms(aid, nbr->getIdx())->getBondType() ==
Bond::DOUBLE)) {
// here's the double bonded oxygen
dbl_to_O = mol.getBondBetweenAtoms(aid, *nid1);
O_atom = mol.getAtomWithIdx(*nid1);
} else if ((mol.getAtomWithIdx(*nid1)->getAtomicNum() == 6 ||
mol.getAtomWithIdx(*nid1)->getAtomicNum() == 7) &&
(mol.getAtomWithIdx(*nid1)->getDegree() >= 2) &&
(mol.getBondBetweenAtoms(aid, *nid1)->getBondType() ==
dbl_to_O = mol.getBondBetweenAtoms(aid, nbr->getIdx());
O_atom = nbr;
} else if ((nbr->getAtomicNum() == 6 || nbr->getAtomicNum() == 7) &&
(nbr->getDegree() >= 2) &&
(mol.getBondBetweenAtoms(aid, nbr->getIdx())->getBondType() ==
Bond::DOUBLE)) {
hasDoubleToCorN = true;
}
++nid1;
} // end of loop over the first neigh
if (hasDoubleToCorN && dbl_to_O != nullptr) {
TEST_ASSERT(O_atom != nullptr);
@@ -165,30 +155,23 @@ void halogenCleanup(RWMol &mol, Atom *atom) {
// X(=O)O -> [X+]([O-])O
int ev = atom->calcExplicitValence(false);
if (atom->getFormalCharge() == 0 && (ev == 7 || ev == 5 || ev == 3)) {
unsigned int aid = atom->getIdx();
bool neighborsAllO = true;
RWMol::ADJ_ITER nid1, end1;
boost::tie(nid1, end1) = mol.getAtomNeighbors(atom);
while (nid1 != end1) {
if (mol.getAtomWithIdx(*nid1)->getAtomicNum() != 8) {
for (const auto nbr : mol.atomNeighbors(atom)) {
if (nbr->getAtomicNum() != 8) {
neighborsAllO = false;
break;
}
++nid1;
}
if (neighborsAllO) {
int formalCharge = 0;
boost::tie(nid1, end1) = mol.getAtomNeighbors(atom);
while (nid1 != end1) {
Bond *b = mol.getBondBetweenAtoms(aid, *nid1);
if (b->getBondType() == Bond::DOUBLE) {
b->setBondType(Bond::SINGLE);
Atom *otherAtom = mol.getAtomWithIdx(*nid1);
for (auto bond : mol.atomBonds(atom)) {
if (bond->getBondType() == Bond::DOUBLE) {
bond->setBondType(Bond::SINGLE);
auto otherAtom = bond->getOtherAtom(atom);
formalCharge++;
otherAtom->setFormalCharge(-1);
otherAtom->calcExplicitValence(false);
}
++nid1;
}
atom->setFormalCharge(formalCharge);
atom->calcExplicitValence(false);
@@ -490,13 +473,11 @@ std::vector<ROMOL_SPTR> getMolFrags(const ROMol &mol, bool sanitizeFrags,
}
// loop over neighbors and add bonds in the fragment to all atoms
// that are already in the same fragment
ROMol::ADJ_ITER nbrIdx, endNbrs;
boost::tie(nbrIdx, endNbrs) = mol.getAtomNeighbors(oAtm);
while (nbrIdx != endNbrs) {
if (copiedAtoms[*nbrIdx]) {
copiedBonds[mol.getBondBetweenAtoms(idx, *nbrIdx)->getIdx()] = 1;
for (const auto nbr : mol.atomNeighbors(oAtm)) {
if (copiedAtoms[nbr->getIdx()]) {
copiedBonds[mol.getBondBetweenAtoms(idx, nbr->getIdx())->getIdx()] =
1;
}
++nbrIdx;
}
}
// update ring stereochemistry information