Ejemplo n.º 1
0
// find the neighbors for an atoms that are not connected by single bond that is
// not refBond
// if checkDir is true only neighbor atoms with bonds marked with a direction
// will be returned
void findAtomNeighborsHelper(const ROMol &mol, const Atom *atom,
                             const Bond *refBond, UINT_VECT &neighbors,
                             bool checkDir = false) {
  PRECONDITION(atom, "bad atom");
  PRECONDITION(refBond, "bad bond");
  neighbors.clear();
  ROMol::OEDGE_ITER beg, end;
  boost::tie(beg, end) = mol.getAtomBonds(atom);
  while (beg != end) {
    const BOND_SPTR bond = mol[*beg];
    Bond::BondDir dir = bond->getBondDir();
    if (bond->getBondType() == Bond::SINGLE &&
        bond->getIdx() != refBond->getIdx()) {
      if (checkDir) {
        if ((dir != Bond::ENDDOWNRIGHT) && (dir != Bond::ENDUPRIGHT)) {
          ++beg;
          continue;
        }
      }
      Atom *nbrAtom = bond->getOtherAtom(atom);
      neighbors.push_back(nbrAtom->getIdx());
    }
    ++beg;
  }
}
Ejemplo n.º 2
0
RWMOL_SPTR initProduct(const ROMOL_SPTR prodTemplateSptr) {
    const ROMol *prodTemplate=prodTemplateSptr.get();
    RWMol *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 ) {
        Atom *oAtom=(*prodTemplate)[*(atItP.first++)].get();
        Atom *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->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);
        }
        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_SPTR 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);
            }
        }
    }
    return RWMOL_SPTR(res);
} // end of initProduct()
Ejemplo n.º 3
0
// 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;
      }
    }
  }
}