Example #1
0
void setBondDirRelativeToAtom(Bond *bond, Atom *atom, Bond::BondDir dir,
                              bool reverse, boost::dynamic_bitset<> &needsDir) {
    PRECONDITION(bond, "bad bond");
    PRECONDITION(atom, "bad atom");
    PRECONDITION(dir == Bond::ENDUPRIGHT || dir == Bond::ENDDOWNRIGHT, "bad dir");
    PRECONDITION(atom == bond->getBeginAtom() || atom == bond->getEndAtom(),
                 "atom doesn't belong to bond");
    // std::cerr<<"\t\t>sbdra :  bond "<<bond->getIdx()<<" atom
    // "<<atom->getIdx()<<" dir: " << dir << " reverse: "<<reverse<<std::endl;
    Atom *oAtom;
    if (bond->getBeginAtom() != atom) {
        reverse = !reverse;
        oAtom = bond->getBeginAtom();
    } else {
        oAtom = bond->getEndAtom();
    }
    if (reverse) {
        dir = (dir == Bond::ENDUPRIGHT ? Bond::ENDDOWNRIGHT : Bond::ENDUPRIGHT);
    }
    // to ensure maximum compatibility, even when a bond has unknown stereo (set
    // explicitly and recorded in _UnknownStereo property), I will still let a
    // direction to be computed. You must check the _UnknownStereo property to
    // make sure whether this bond is explictly set to have no direction info.
    // This makes sense because the direction info are all derived from
    // coordinates, the _UnknownStereo property is like extra metadata to be
    // used with the direction info.
    bond->setBondDir(dir);
    // std::cerr<<"\t\t\t\t -> dir "<<dir<<std::endl;

    // check for other single bonds around the other atom who need their
    // direction set and set it as demanded by the direction of this one:
    ROMol::OEDGE_ITER beg, end;
    boost::tie(beg, end) = oAtom->getOwningMol().getAtomBonds(oAtom);
    while (beg != end) {
        Bond *nbrBond = oAtom->getOwningMol()[*beg].get();
        if (nbrBond != bond && needsDir[nbrBond->getIdx()]) {
            Bond::BondDir nbrDir = Bond::NONE;
            if ((nbrBond->getBeginAtom() == oAtom && bond->getBeginAtom() == oAtom) ||
                    (nbrBond->getEndAtom() == oAtom && bond->getEndAtom() == oAtom)) {
                // both bonds either start or end here; they *must* have different
                // directions:
                nbrDir =
                    (dir == Bond::ENDUPRIGHT ? Bond::ENDDOWNRIGHT : Bond::ENDUPRIGHT);
            } else {
                // one starts here, the other ends here, they need to have the same
                // direction:
                nbrDir = dir;
            }
            nbrBond->setBondDir(nbrDir);
            needsDir[nbrBond->getIdx()] = 0;
            // std::cerr<<"\t\t\t\t update bond "<<nbrBond->getIdx()<<" to dir "<<
            // nbrDir<<std::endl;
        }
        ++beg;
    }
}
Example #2
0
void StandardPDBResidueBondOrders(RWMol *mol)
{
  RWMol::BondIterator bondIt;
  for (bondIt=mol->beginBonds(); bondIt!=mol->endBonds(); ++bondIt) {
    Bond *bond = *bondIt;
    if (bond->getBondType() == Bond::SINGLE) {
      Atom *beg = bond->getBeginAtom();
      Atom *end = bond->getEndAtom();
      if (StandardPDBDoubleBond(mol,beg,end))
        bond->setBondType(Bond::DOUBLE);
    }
  }
}
Example #3
0
RWMOL_SPTR convertTemplateToMol(const ROMOL_SPTR prodTemplateSptr) {
  const ROMol *prodTemplate = prodTemplateSptr.get();
  auto *res = new RWMol();

  // --------- --------- --------- --------- --------- ---------
  // Initialize by making a copy of the product template as a normal molecule.
  // NOTE that we can't just use a normal copy because we do not want to end up
  // with query atoms or bonds in the product.

  // copy in the atoms:
  ROMol::ATOM_ITER_PAIR atItP = prodTemplate->getVertices();
  while (atItP.first != atItP.second) {
    const Atom *oAtom = (*prodTemplate)[*(atItP.first++)];
    auto *newAtom = new Atom(*oAtom);
    res->addAtom(newAtom, false, true);
    int mapNum;
    if (newAtom->getPropIfPresent(common_properties::molAtomMapNumber,
                                  mapNum)) {
      // set bookmarks for the mapped atoms:
      res->setAtomBookmark(newAtom, mapNum);
      // now clear the molAtomMapNumber property so that it doesn't
      // end up in the products (this was bug 3140490):
      newAtom->clearProp(common_properties::molAtomMapNumber);
      newAtom->setProp<int>(common_properties::reactionMapNum, mapNum);
    }

    newAtom->setChiralTag(Atom::CHI_UNSPECIFIED);
    // if the product-template atom has the inversion flag set
    // to 4 (=SET), then bring its stereochem over, otherwise we'll
    // ignore it:
    int iFlag;
    if (oAtom->getPropIfPresent(common_properties::molInversionFlag, iFlag)) {
      if (iFlag == 4) newAtom->setChiralTag(oAtom->getChiralTag());
    }

    // check for properties we need to set:
    int val;
    if (newAtom->getPropIfPresent(common_properties::_QueryFormalCharge, val)) {
      newAtom->setFormalCharge(val);
    }
    if (newAtom->getPropIfPresent(common_properties::_QueryHCount, val)) {
      newAtom->setNumExplicitHs(val);
      newAtom->setNoImplicit(true);  // this was github #1544
    }
    if (newAtom->getPropIfPresent(common_properties::_QueryMass, val)) {
      // FIX: technically should do something with this
      // newAtom->setMass(val);
    }
    if (newAtom->getPropIfPresent(common_properties::_QueryIsotope, val)) {
      newAtom->setIsotope(val);
    }
  }
  // and the bonds:
  ROMol::BOND_ITER_PAIR bondItP = prodTemplate->getEdges();
  while (bondItP.first != bondItP.second) {
    const Bond *oldB = (*prodTemplate)[*(bondItP.first++)];
    unsigned int bondIdx;
    bondIdx = res->addBond(oldB->getBeginAtomIdx(), oldB->getEndAtomIdx(),
                           oldB->getBondType()) -
              1;
    // make sure we don't lose the bond dir information:
    Bond *newB = res->getBondWithIdx(bondIdx);
    newB->setBondDir(oldB->getBondDir());
    // Special case/hack:
    //  The product has been processed by the SMARTS parser.
    //  The SMARTS parser tags unspecified bonds as single, but then adds
    //  a query so that they match single or double
    //  This caused Issue 1748846
    //   http://sourceforge.net/tracker/index.php?func=detail&aid=1748846&group_id=160139&atid=814650
    //  We need to fix that little problem now:
    if (oldB->hasQuery()) {
      //  remember that the product has been processed by the SMARTS parser.
      std::string queryDescription = oldB->getQuery()->getDescription();
      if (queryDescription == "BondOr" && oldB->getBondType() == Bond::SINGLE) {
        //  We need to fix that little problem now:
        if (newB->getBeginAtom()->getIsAromatic() &&
            newB->getEndAtom()->getIsAromatic()) {
          newB->setBondType(Bond::AROMATIC);
          newB->setIsAromatic(true);
        } else {
          newB->setBondType(Bond::SINGLE);
          newB->setIsAromatic(false);
        }
      } else if (queryDescription == "BondNull") {
        newB->setProp(common_properties::NullBond, 1);
      }
    }
    // copy properties over:
    bool preserveExisting = true;
    newB->updateProps(*static_cast<const RDProps *>(oldB), preserveExisting);
  }
  return RWMOL_SPTR(res);
}  // end of convertTemplateToMol()