void CleanupMolecule() { // an example of doing some cleaning up of a molecule before // calling the sanitizeMol function() // build: C1CC1C(:O):O RWMol *mol = new RWMol(); // add atoms and bonds: mol->addAtom(new Atom(6)); // atom 0 mol->addAtom(new Atom(6)); // atom 1 mol->addAtom(new Atom(6)); // atom 2 mol->addAtom(new Atom(6)); // atom 3 mol->addAtom(new Atom(8)); // atom 4 mol->addAtom(new Atom(8)); // atom 5 mol->addBond(3, 4, Bond::AROMATIC); // bond 0 mol->addBond(3, 5, Bond::AROMATIC); // bond 1 mol->addBond(3, 2, Bond::SINGLE); // bond 2 mol->addBond(2, 1, Bond::SINGLE); // bond 3 mol->addBond(1, 0, Bond::SINGLE); // bond 4 mol->addBond(0, 2, Bond::SINGLE); // bond 5 // instead of calling sanitize mol, which would generate an error, // we'll perceive the rings, then take care of aromatic bonds // that aren't in a ring, then sanitize: MolOps::findSSSR(*mol); for (ROMol::BondIterator bondIt = mol->beginBonds(); bondIt != mol->endBonds(); ++bondIt) { if (((*bondIt)->getIsAromatic() || (*bondIt)->getBondType() == Bond::AROMATIC) && !mol->getRingInfo()->numBondRings((*bondIt)->getIdx())) { // remove the aromatic flag on the bond: (*bondIt)->setIsAromatic(false); // and cleanup its attached atoms as well (they were // also marked aromatic when the bond was added) (*bondIt)->getBeginAtom()->setIsAromatic(false); (*bondIt)->getEndAtom()->setIsAromatic(false); // NOTE: this isn't really reasonable: (*bondIt)->setBondType(Bond::SINGLE); } } // now it's safe to sanitize: RDKit::MolOps::sanitizeMol(*mol); // Get the canonical SMILES, include stereochemistry: std::string smiles; smiles = MolToSmiles(*(static_cast<ROMol *>(mol)), true); BOOST_LOG(rdInfoLog) << " fixed SMILES: " << smiles << 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; }