const std::string GetMolFileQueryInfo(const RWMol &mol){ std::stringstream ss; boost::dynamic_bitset<> listQs(mol.getNumAtoms()); for(ROMol::ConstAtomIterator atomIt=mol.beginAtoms(); atomIt!=mol.endAtoms();++atomIt){ if(hasListQuery(*atomIt)) listQs.set((*atomIt)->getIdx()); } for(ROMol::ConstAtomIterator atomIt=mol.beginAtoms(); atomIt!=mol.endAtoms();++atomIt){ if(!listQs[(*atomIt)->getIdx()] && hasComplexQuery(*atomIt)){ std::string sma=SmartsWrite::GetAtomSmarts(static_cast<const QueryAtom *>(*atomIt)); ss<< "V "<<std::setw(3)<<(*atomIt)->getIdx()+1<<" "<<sma<<std::endl; } } for(ROMol::ConstAtomIterator atomIt=mol.beginAtoms(); atomIt!=mol.endAtoms();++atomIt){ if(listQs[(*atomIt)->getIdx()]){ INT_VECT vals; getListQueryVals((*atomIt)->getQuery(),vals); ss<<"M ALS "<<std::setw(3)<<(*atomIt)->getIdx()+1<<" "; ss<<std::setw(2)<<vals.size(); if((*atomIt)->getQuery()->getNegation()){ ss<<" T"; } else { ss<<" F"; } BOOST_FOREACH(int val,vals){ ss<<" "<<std::setw(3)<<std::left<<(PeriodicTable::getTable()->getElementSymbol(val)); } ss<<"\n"; } }
void prepareMolForDrawing(RWMol &mol, bool kekulize, bool addChiralHs, bool wedgeBonds, bool forceCoords) { if (kekulize) { MolOps::Kekulize(mol, false); // kekulize, but keep the aromatic flags! } if (addChiralHs) { std::vector<unsigned int> chiralAts; for (RWMol::AtomIterator atIt = mol.beginAtoms(); atIt != mol.endAtoms(); ++atIt) { if ((*atIt)->getChiralTag() == Atom::CHI_TETRAHEDRAL_CCW || (*atIt)->getChiralTag() == Atom::CHI_TETRAHEDRAL_CW) { chiralAts.push_back((*atIt)->getIdx()); } } if (chiralAts.size()) { bool addCoords = false; if (!forceCoords && mol.getNumConformers()) addCoords = true; MolOps::addHs(mol, false, addCoords, &chiralAts); } } if (forceCoords || !mol.getNumConformers()) { RDDepict::compute2DCoords(mol); } if (wedgeBonds) { WedgeMolBonds(mol, &mol.getConformer()); } }
void prepareMolForDrawing(RWMol &mol, bool kekulize, bool addChiralHs, bool wedgeBonds, bool forceCoords) { if (kekulize) { MolOps::Kekulize(mol, false); // kekulize, but keep the aromatic flags! } if (addChiralHs) { std::vector<unsigned int> chiralAts; for (RWMol::AtomIterator atIt = mol.beginAtoms(); atIt != mol.endAtoms(); ++atIt) { if (isAtomCandForChiralH(mol, *atIt)) { chiralAts.push_back((*atIt)->getIdx()); } } if (chiralAts.size()) { bool addCoords = false; if (!forceCoords && mol.getNumConformers()) addCoords = true; MolOps::addHs(mol, false, addCoords, &chiralAts); } } if (forceCoords || !mol.getNumConformers()) { // compute 2D coordinates in a standard orientation: const bool canonOrient = true; RDDepict::compute2DCoords(mol, NULL, canonOrient); } if (wedgeBonds) { WedgeMolBonds(mol, &mol.getConformer()); } }
// handles stereochem markers set by the Mol file parser and // converts them to the RD standard: void DetectAtomStereoChemistry(RWMol &mol, const Conformer *conf) { PRECONDITION(conf, "no conformer"); // make sure we've calculated the implicit valence on each atom: for (RWMol::AtomIterator atomIt = mol.beginAtoms(); atomIt != mol.endAtoms(); ++atomIt) { (*atomIt)->calcImplicitValence(false); } for (RWMol::BondIterator bondIt = mol.beginBonds(); bondIt != mol.endBonds(); ++bondIt) { Bond *bond = *bondIt; if (bond->getBondDir() != Bond::UNKNOWN) { Bond::BondDir dir = bond->getBondDir(); // the bond is marked as chiral: if (dir == Bond::BEGINWEDGE || dir == Bond::BEGINDASH) { Atom *atom = bond->getBeginAtom(); if (atom->getImplicitValence() == -1) { atom->calcExplicitValence(); atom->calcImplicitValence(); } Atom::ChiralType code = FindAtomStereochemistry(mol, bond, conf); atom->setChiralTag(code); // within the RD representation, if a three-coordinate atom // is chiral and has an implicit H, that H needs to be made explicit: if (atom->getDegree() == 3 && !atom->getNumExplicitHs() && atom->getNumImplicitHs() == 1) { atom->setNumExplicitHs(1); // recalculated number of implicit Hs: atom->updatePropertyCache(); } } } } }
void testProps() { BOOST_LOG(rdInfoLog) << "-----------------------\n properties" << std::endl; string smi = "C1COC1"; RWMol *m = SmilesToMol(smi, 0, false); m = SmilesToMol(smi, 0, false); for (ROMol::AtomIterator ai = m->beginAtoms(); ai != m->endAtoms(); ++ai) { unsigned int v = 1; (*ai)->setProp("foo", v, true); } m = SmilesToMol(smi, 0, false); for (ROMol::BondIterator ai = m->beginBonds(); ai != m->endBonds(); ++ai) { unsigned int v = 1; (*ai)->setProp("foo", v, true); } m = SmilesToMol(smi, 0, false); for (ROMol::AtomIterator ai = m->beginAtoms(); ai != m->endAtoms(); ++ai) { unsigned int v = 1; (*ai)->setProp("foo", v, true); (*ai)->setProp("bar", v, true); } m = SmilesToMol(smi, 0, false); for (ROMol::AtomIterator ai = m->beginAtoms(); ai != m->endAtoms(); ++ai) { unsigned int v = 1; (*ai)->setProp("foo", v, true); (*ai)->setProp("bar", v, true); (*ai)->setProp("baz", v, true); } m = SmilesToMol(smi, 0, false); for (ROMol::AtomIterator ai = m->beginAtoms(); ai != m->endAtoms(); ++ai) { unsigned int v = 1; (*ai)->setProp("foo", v, false); } m = SmilesToMol(smi, 0, false); for (ROMol::AtomIterator ai = m->beginAtoms(); ai != m->endAtoms(); ++ai) { unsigned int v = 1; (*ai)->setProp("foo", v, false); (*ai)->setProp("bar", v, false); } m = SmilesToMol(smi, 0, false); for (ROMol::AtomIterator ai = m->beginAtoms(); ai != m->endAtoms(); ++ai) { unsigned int v = 1; (*ai)->setProp("foo", v, false); (*ai)->setProp("bar", v, false); (*ai)->setProp("baz", v, false); } BOOST_LOG(rdInfoLog) << "Finished" << std::endl; }
int setAromaticity(RWMol &mol) { // FIX: we will assume for now that if the input molecule came // with aromaticity information it is correct and we will not // touch it. Loop through the atoms and check if any atom has // arom stuff set. We may want check this more carefully later // and start from scratch if necessary ROMol::AtomIterator ai; for (ai = mol.beginAtoms(); ai != mol.endAtoms(); ai++) { if ((*ai)->getIsAromatic()) { // found aromatic info return -1; } } // first find the all the simple rings in the molecule VECT_INT_VECT srings; if (mol.getRingInfo()->isInitialized()) { srings = mol.getRingInfo()->atomRings(); } else { MolOps::symmetrizeSSSR(mol, srings); } int narom = 0; // loop over all the atoms in the rings that can be candidates // for aromaticity // Atoms are candidates if // - it is part of ring // - has one or more electron to donate or has empty p-orbitals int natoms = mol.getNumAtoms(); boost::dynamic_bitset<> acands(natoms); boost::dynamic_bitset<> aseen(natoms); VECT_EDON_TYPE edon(natoms); VECT_INT_VECT cRings; // holder for rings that are candidates for aromaticity for (VECT_INT_VECT_I vivi = srings.begin(); vivi != srings.end(); ++vivi) { bool allAromatic = true; for (INT_VECT_I ivi = (*vivi).begin(); ivi != (*vivi).end(); ++ivi) { if (aseen[*ivi]) { if (!acands[*ivi]) allAromatic = false; continue; } aseen[*ivi] = 1; Atom *at = mol.getAtomWithIdx(*ivi); // now that the atom is part of ring check if it can donate // electron or has empty orbitals. Record the donor type // information in 'edon' - we will need it when we get to // the Huckel rule later edon[*ivi] = getAtomDonorTypeArom(at); acands[*ivi] = isAtomCandForArom(at, edon[*ivi]); if (!acands[*ivi]) allAromatic = false; } if (allAromatic) { cRings.push_back((*vivi)); } } // first convert all rings to bonds ids VECT_INT_VECT brings; RingUtils::convertToBonds(cRings, brings, mol); // make the neighbor map for the rings // i.e. a ring is a neighbor a another candidate ring if // shares at least one bond // useful to figure out fused systems INT_INT_VECT_MAP neighMap; RingUtils::makeRingNeighborMap(brings, neighMap, maxFusedAromaticRingSize); // now loop over all the candidate rings and check the // huckel rule - of course paying attention to fused systems. INT_VECT doneRs; int curr = 0; int cnrs = rdcast<int>(cRings.size()); boost::dynamic_bitset<> fusDone(cnrs); INT_VECT fused; while (curr < cnrs) { fused.resize(0); RingUtils::pickFusedRings(curr, neighMap, fused, fusDone); applyHuckelToFused(mol, cRings, brings, fused, edon, neighMap, narom, 6); int rix; for (rix = 0; rix < cnrs; rix++) { if (!fusDone[rix]) { curr = rix; break; } } if (rix == cnrs) { break; } } mol.setProp(common_properties::numArom, narom, true); return narom; }
bool StripSmallFragments(RWMol &mol, bool verbose) { const bool sanitize=false; std::vector<boost::shared_ptr<ROMol> > frags = MolOps::getMolFrags(mol, sanitize); if (frags.size() <= 1) return false; size_t maxFragSize = 0; size_t maxFragIdx = 0; for(size_t i=0; i<frags.size(); ++i) { const unsigned int fragSize = frags[i].get()->getNumAtoms(); if(fragSize >= maxFragSize) { maxFragSize = fragSize; maxFragIdx = i; } } if(verbose) { std::string name = "<no name>"; mol.getPropIfPresent(common_properties::_Name, name); for(size_t i=0; i<frags.size(); ++i) { if (i != maxFragIdx) { BOOST_LOG(rdWarningLog) << name << " removed fragment i="<<i<<" with " << frags[i].get()->getNumAtoms() << " atoms" << std::endl; } } } // we need to save chirality for checking later bool checkChiral = false; if(mol.hasProp(RDKit::common_properties::_MolFileChiralFlag)) { unsigned int chiralflag = mol.getProp<unsigned int>( RDKit::common_properties::_MolFileChiralFlag); frags[maxFragIdx].get()->setProp<unsigned int>( RDKit::common_properties::_MolFileChiralFlag, chiralflag); checkChiral = chiralflag != 0; } mol = *frags[maxFragIdx].get(); // We need to see if the mol file's chirality possibly came from this // fragment. if (checkChiral) { bool ischiral = false; RWMol copy(mol); try { MolOps::sanitizeMol(copy); ClearSingleBondDirFlags(copy); const Conformer &conf = copy.getConformer(); DetectBondStereoChemistry(copy, &conf); MolOps::assignStereochemistry(copy, true, true, true); for (ROMol::AtomIterator atIt =copy.beginAtoms(); atIt != copy.endAtoms(); ++atIt) { if((*atIt)->hasProp(common_properties::_ChiralityPossible)) { ischiral = true; checkChiral = false; break; } } } catch (...) { } // are chiral tags set if(checkChiral) { for (ROMol::AtomIterator atIt = mol.beginAtoms(); atIt != mol.endAtoms(); ++atIt) { if ( (*atIt)->getChiralTag() == Atom::CHI_TETRAHEDRAL_CW || (*atIt)->getChiralTag() == Atom::CHI_TETRAHEDRAL_CCW ) { ischiral = true; break; } } for (ROMol::BondIterator bondIt = mol.beginBonds(); bondIt != mol.endBonds(); ++bondIt) { if ((*bondIt)->getBondDir() == Bond::BEGINDASH || (*bondIt)->getBondDir() == Bond::BEGINWEDGE) { ischiral = true; break; } } } if (!ischiral) { mol.setProp<unsigned int>(RDKit::common_properties::_MolFileChiralFlag, 0); } } return true; }