bool bondCompat(const BOND_SPTR &b1, const BOND_SPTR &b2, bool useQueryQueryMatches) { PRECONDITION(b1, "bad bond"); PRECONDITION(b2, "bad bond"); bool res; if (useQueryQueryMatches && b1->hasQuery() && b2->hasQuery()) { res = static_cast<QueryBond *>(b1.get())->QueryMatch( static_cast<QueryBond *>(b2.get())); } else { res = b1->Match(b2); } if (res && b1->getBondType() == Bond::DATIVE && b2->getBondType() == Bond::DATIVE) { // for dative bonds we need to make sure that the direction also matches: if (!b1->getBeginAtom()->Match(b1->getBeginAtom()) || !b1->getEndAtom()->Match(b2->getEndAtom())) { res = false; } } // std::cout << "\t\tbondCompat: "<< b1->getIdx() << "-" << b2->getIdx() << ": // " << res << std::endl; return res; }
// construct a vector with <atomIdx,direction> pairs for // neighbors of a given atom. This list will only be // non-empty if at least one of the bonds has its direction // set. void findAtomNeighborDirHelper(const ROMol &mol, const Atom *atom, const Bond *refBond, UINT_VECT &ranks, INT_PAIR_VECT &neighbors, bool &hasExplicitUnknownStereo) { PRECONDITION(atom, "bad atom"); PRECONDITION(refBond, "bad bond"); bool seenDir = false; ROMol::OEDGE_ITER beg, end; boost::tie(beg, end) = mol.getAtomBonds(atom); while (beg != end) { const BOND_SPTR bond = mol[*beg]; // check whether this bond is explictly set to have unknown stereo if (!hasExplicitUnknownStereo) { int explicit_unknown_stereo; if (bond->getBondDir() == Bond::UNKNOWN // there's a squiggle bond || (bond->getPropIfPresent<int>(common_properties::_UnknownStereo, explicit_unknown_stereo) && explicit_unknown_stereo)) hasExplicitUnknownStereo = true; } Bond::BondDir dir = bond->getBondDir(); if (bond->getIdx() != refBond->getIdx()) { if (dir == Bond::ENDDOWNRIGHT || dir == Bond::ENDUPRIGHT) { seenDir = true; // If we're considering the bond "backwards", (i.e. from end // to beginning, reverse the effective direction: if (atom != bond->getBeginAtom()) { if (dir == Bond::ENDDOWNRIGHT) dir = Bond::ENDUPRIGHT; else dir = Bond::ENDDOWNRIGHT; } } Atom *nbrAtom = bond->getOtherAtom(atom); neighbors.push_back(std::make_pair(nbrAtom->getIdx(), dir)); } ++beg; } if (!seenDir) { neighbors.clear(); } else { if (neighbors.size() == 2 && ranks[neighbors[0].first] == ranks[neighbors[1].first]) { // the two substituents are identical, no stereochemistry here: neighbors.clear(); } else { // it's possible that direction was set only one of the bonds, set the // other // bond's direction to be reversed: if (neighbors[0].second != Bond::ENDDOWNRIGHT && neighbors[0].second != Bond::ENDUPRIGHT) { CHECK_INVARIANT(neighbors.size() > 1, "too few neighbors"); neighbors[0].second = neighbors[1].second == Bond::ENDDOWNRIGHT ? Bond::ENDUPRIGHT : Bond::ENDDOWNRIGHT; } else if (neighbors.size() > 1 && neighbors[1].second != Bond::ENDDOWNRIGHT && neighbors[1].second != Bond::ENDUPRIGHT) { neighbors[1].second = neighbors[0].second == Bond::ENDDOWNRIGHT ? Bond::ENDUPRIGHT : Bond::ENDDOWNRIGHT; } } } }