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()); } }
//************************************************************************************* // // Adds 2D coordinates to a molecule using the Depict.dll // // ARGUMENTS: // mol: the molecule to be altered // tempFilename: (OPTIONAL) the name of the temporary file // // RETURNS: // 1 on success, 0 otherwise // // Here's the process by which this works (it's kind of contorted): // 1) convert the mol to SMILES // 2) use the DLL to convert the SMILES to a mol file (on disk) // 3) parse the mol file into a temporary molecule // 4) do a substructure match from the old molecule to the // temp one (which may have a different atom numbering or additional // atoms added). // 5) Update the positions of the atoms on the old molecule. // 6) Free the temp molecule. // // NOTES: // - *FIX:* at the moment we're not doing anything to clear up the // temp file created in this process. It'll always have the same // name unless the user explicitly asks that we do something different. // - To use the DLL, it's essential that the COMBICHEM_ROOT and COMBICHEM_RELEASE // environment variables be set. If this isn't done, this whole process // will fail. // - See the notes above about failures when opening the DLL. // //************************************************************************************* int Add2DCoordsToMolDLL(ROMol &mol,std::string tempFilename){ std::string smi=MolToSmiles(mol,true); int tmp = SmilesToMolFileDLL(smi,tempFilename); int res = -1; if(tmp){ // build another mol from that mol file: RWMol *tmpMol = MolFileToMol(tempFilename,false); // match it up with the starting mol: // (We need to do this because the depict.dll conversion // to a mol file may have added Hs) MatchVectType matchVect; bool hasMatch=SubstructMatch(tmpMol,&mol,matchVect); if(hasMatch){ const Conformer &conf = tmpMol->getCoformer(0); Coformer *nconf = new Coformer(mol.getNumAtoms()); for(MatchVectType::const_iterator mvi=matchVect.begin(); mvi!=matchVect.end();mvi++){ nconf->setAtomPos(conf.getAtomPos(mvi->first)); } confId = (int)mol.addConformer(nconf, true); } delete tmpMol; } return res; }
void runSDFile(std::string fileName,int checkEvery=10){ SDMolSupplier suppl(fileName,false); RWMol *mol; mol = (RWMol *)suppl.next(); while(mol){ std::string name; mol->getProp("_Name",name); std::cerr << "Mol: " << name << std::endl; try{ MolOps::sanitizeMol(*mol); } catch (...) { std::cerr << " sanitization failed" << std::endl; delete mol; mol = 0; } if(mol){ ROMol *mol2=MolOps::addHs(*mol,false,true); delete mol; runMol(mol2,checkEvery,false); delete mol2; } mol = (RWMol *)suppl.next(); } }
// 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 testIssue3399798(std::string rdbase){ BOOST_LOG(rdInfoLog) << "---------------------------------------" << std::endl; BOOST_LOG(rdInfoLog) << "-- testing issue 3399798 --" << std::endl; BOOST_LOG(rdInfoLog) << "---------------------------------------" << std::endl; { std::string fName = rdbase + "/Code/GraphMol/FileParsers/test_data/Issue3399798.mol2"; RWMol *m = Mol2FileToMol(fName); TEST_ASSERT(m); TEST_ASSERT(m->getAtomWithIdx(0)->getChiralTag()==Atom::CHI_UNSPECIFIED); TEST_ASSERT(m->getAtomWithIdx(3)->getChiralTag()==Atom::CHI_UNSPECIFIED); delete m; } { std::string fName = rdbase + "/Code/GraphMol/FileParsers/test_data/Issue3399798.2.mol2"; RWMol *m = Mol2FileToMol(fName); TEST_ASSERT(m); TEST_ASSERT(m->getAtomWithIdx(0)->getChiralTag()==Atom::CHI_UNSPECIFIED); TEST_ASSERT(m->getAtomWithIdx(3)->getChiralTag()!=Atom::CHI_UNSPECIFIED); delete m; } BOOST_LOG(rdInfoLog) << "------------------------------------" << std::endl; BOOST_LOG(rdInfoLog) << "-- DONE --" << std::endl; BOOST_LOG(rdInfoLog) << "------------------------------------" << std::endl; }
void testGithub438(std::string rdbase) { BOOST_LOG(rdInfoLog) << "-----------------------------------" << std::endl; BOOST_LOG(rdInfoLog) << "-- testing GitHub issue #438: problems with metals in mol2 files --" << std::endl; BOOST_LOG(rdInfoLog) << "-----------------------------------" << std::endl; { std::string fName = rdbase + "/Code/GraphMol/FileParsers/test_data/github438_1.mol2"; RWMol *mol = Mol2FileToMol(fName); TEST_ASSERT(mol); TEST_ASSERT(mol->getAtomWithIdx(0)->getFormalCharge() == 1); delete mol; } { std::string fName = rdbase + "/Code/GraphMol/FileParsers/test_data/github438_2.mol2"; RWMol *mol = Mol2FileToMol(fName); TEST_ASSERT(mol); TEST_ASSERT(mol->getAtomWithIdx(0)->getFormalCharge() == 2); delete mol; } BOOST_LOG(rdInfoLog) << "------------------------------------" << std::endl; BOOST_LOG(rdInfoLog) << "-- DONE --" << std::endl; BOOST_LOG(rdInfoLog) << "------------------------------------" << std::endl; }
void testGithubIssue429() { BOOST_LOG(rdInfoLog) << "-------------------------------------" << std::endl; BOOST_LOG(rdInfoLog) << "Testing github issue 429: fragmentOnSomeBonds() should update implicit H count on aromatic heteroatoms when addDummies is False"<< std::endl; { std::string smi = "c1cccn1CC1CC1"; RWMol *mol = SmilesToMol(smi); TEST_ASSERT(mol); TEST_ASSERT(mol->getNumAtoms()); unsigned int indices[]={4,5}; std::vector<unsigned int> bindices(indices,indices+(sizeof(indices)/sizeof(indices[0]))); std::vector<ROMOL_SPTR> frags; MolFragmenter::fragmentOnSomeBonds(*mol,bindices,frags,1,false); TEST_ASSERT(frags.size()==2); std::vector<std::vector<int> > fragMap; BOOST_FOREACH(ROMOL_SPTR romol,frags){ RWMol *rwmol=(RWMol *)(romol.get()); MolOps::sanitizeMol(*rwmol); } // we actually changed fragmentOnBonds(), check that too: RWMol *nmol=(RWMol *)MolFragmenter::fragmentOnBonds(*mol,bindices,false); MolOps::sanitizeMol(*nmol); delete nmol; delete mol; }
void testUFFBuilderSpecialCases(){ BOOST_LOG(rdErrorLog) << "-------------------------------------" << std::endl; BOOST_LOG(rdErrorLog) << " Testing UFF special cases." << std::endl; RWMol *mol; std::string key; int needMore; RDGeom::Point3D v1,v2; ForceFields::ForceField *field; std::string pathName=getenv("RDBASE"); pathName += "/Code/GraphMol/ForceFieldHelpers/UFF/test_data"; // ---------- // Trigonal bipyramid // ---------- mol = MolFileToMol(pathName+"/tbp.mol",false); TEST_ASSERT(mol); MolOps::sanitizeMol(*mol); const Conformer &conf = mol->getConformer(); field=UFF::constructForceField(*mol); TEST_ASSERT(field); field->initialize(); needMore = field->minimize(200,1e-8,1e-4); TEST_ASSERT(!needMore); v1 = conf.getAtomPos(0).directionVector(conf.getAtomPos(1)); v2 = conf.getAtomPos(0).directionVector(conf.getAtomPos(2)); TEST_ASSERT(feq(v1.dotProduct(v2),-1.0,1e-3)); v2 = conf.getAtomPos(0).directionVector(conf.getAtomPos(3)); TEST_ASSERT(feq(v1.dotProduct(v2),0.0,1e-3)); v2 = conf.getAtomPos(0).directionVector(conf.getAtomPos(4)); TEST_ASSERT(feq(v1.dotProduct(v2),0.0,1e-3)); v2 = conf.getAtomPos(0).directionVector(conf.getAtomPos(5)); TEST_ASSERT(feq(v1.dotProduct(v2),0.0,1e-3)); v1 = conf.getAtomPos(0).directionVector(conf.getAtomPos(2)); v2 = conf.getAtomPos(0).directionVector(conf.getAtomPos(3)); TEST_ASSERT(feq(v1.dotProduct(v2),0.0,1e-3)); v2 = conf.getAtomPos(0).directionVector(conf.getAtomPos(4)); TEST_ASSERT(feq(v1.dotProduct(v2),0.0,1e-3)); v2 = conf.getAtomPos(0).directionVector(conf.getAtomPos(5)); TEST_ASSERT(feq(v1.dotProduct(v2),0.0,1e-3)); v1 = conf.getAtomPos(0).directionVector(conf.getAtomPos(3)); v2 = conf.getAtomPos(0).directionVector(conf.getAtomPos(4)); TEST_ASSERT(feq(v1.dotProduct(v2),-0.5,1e-3)); v2 = conf.getAtomPos(0).directionVector(conf.getAtomPos(5)); TEST_ASSERT(feq(v1.dotProduct(v2),-0.5,1e-3)); v1 = conf.getAtomPos(0).directionVector(conf.getAtomPos(4)); v2 = conf.getAtomPos(0).directionVector(conf.getAtomPos(5)); TEST_ASSERT(feq(v1.dotProduct(v2),-0.5,1e-3)); delete mol; delete field; BOOST_LOG(rdErrorLog) << " done" << std::endl; }
void testPaths2() { std::cout << "-----------------------\n Path retrieval2" << std::endl; // build: CCC(C)CC RWMol mol; bool updateLabel = true; bool takeOwnership = true; mol.addAtom(new Atom(6), updateLabel, takeOwnership); mol.addAtom(new Atom(6), updateLabel, takeOwnership); mol.addAtom(new Atom(6), updateLabel, takeOwnership); mol.addAtom(new Atom(6), updateLabel, takeOwnership); mol.addBond(0, 1, Bond::SINGLE); mol.addBond(1, 2, Bond::SINGLE); mol.addBond(2, 3, Bond::SINGLE); mol.addBond(2, 0, Bond::SINGLE); // // Retrieve using bonds // PATH_LIST tmp = findAllPathsOfLengthN(mol, 3); // std::cout << "\n3:" << std::endl; // dumpVIV(tmp); CHECK_INVARIANT(tmp.size() == 3, ""); std::cout << "Finished" << std::endl; }
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()); } }
void test4Coulomb () { std::string path = getenv("RDBASE"); path += "/Code/GraphMol/MIF/test_data/"; RWMol mol = *MolFileToMol(path + "HCl.mol", true, false); computeGasteigerCharges(mol); std::vector<double> charges; std::vector<Point3D> pos; Conformer conf = mol.getConformer(0); for (int i = 0; i < mol.getNumAtoms(); ++i) { charges.push_back(mol.getAtomWithIdx (i)->getProp<double> ("_GasteigerCharge")); pos.push_back(conf.getAtomPos(i)); } UniformRealValueGrid3D grd = *constructGrid(mol); UniformRealValueGrid3D grd2 = *constructGrid(mol); Coulomb coul(mol); calculateDescriptors<Coulomb>(grd, coul); calculateDescriptors<Coulomb>(grd2, Coulomb (charges, pos)); CHECK_INVARIANT(grd.compareGrids(grd2), "Coulomb: Different constructors do not yield the same descriptor."); CHECK_INVARIANT(feq (coul(0.0,0.0,0.0, 1000), 0.0), "Coulomb: Potential between atoms wrong.(should be 0)"); CHECK_INVARIANT(coul(2.0,0.0,0.0, 1000) < 0, "Coulomb: Potential between positive charges not positive."); CHECK_INVARIANT(coul(-2.0,0.0,0.0, 1000) > 0, "Coulomb: Potential between positive and negative charges not negative."); CHECK_INVARIANT(feq(coul(0.0,0.0,0.0, 0.1), 0.0), "Coulomb: Small threshold dist does not give 0."); calculateDescriptors<Coulomb>(grd, Coulomb(mol, 0, 1.0, true)); for (unsigned int i = 0; i < grd.getSize(); i++) { CHECK_INVARIANT(grd.getVal (i) <= 0.0, "Coulomb: Absolute value field not negative"); } Coulomb coul1(mol, 0, -1.0, false, "_GasteigerCharge", 0.0, 0.01); CHECK_INVARIANT(coul1(-2.0, 0.0, 0.0, 1000) < 0, "Coulomb: Potential between negative charges not positive."); CHECK_INVARIANT(coul1(2.0, 0.0, 0.0, 1000) > 0, "Coulomb: Potential between positive and negative charges not negative."); Coulomb coul2 = Coulomb(mol, 0, -.5, false, "_GasteigerCharge", 0.0, 0.01); CHECK_INVARIANT(coul1(-2.0, 0.0, 0.0, 1000) < coul2 (-2.0, 0.0, 0.0, 1000), "Coulomb: Higher probecharge does not result in stronger forces."); Coulomb coul3(mol, 0, 1.0, false, "_GasteigerCharge", 0.01, 1.0); CHECK_INVARIANT(coul3(0.0, 0.0, 0.0, 1000) > coul3(0.1, 0.0, 0.0, 1000), "Coulomb: Softcore interaction wrong."); CHECK_INVARIANT(coul3(0.66, 0.0, 0.0, 1000) > coul3(0.68, 0.0, 0.0, 1000), "Coulomb: Softcore interaction wrong."); CHECK_INVARIANT(coul3(0.70, 0.0, 0.0, 1000) > coul3(0.68, 0.0, 0.0, 1000), "Coulomb: Softcore interaction wrong."); CHECK_INVARIANT(feq(coul3(0.0,0.0,0.0, 0.1), 0.0), "Coulomb: Small threshold dist does not give 0."); }
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; }
void testGetSetBondLength() { std::string rdbase = getenv("RDBASE"); std::string fName = rdbase + "/Code/GraphMol/MolTransforms/test_data/3-cyclohexylpyridine.mol"; RWMol *m = MolFileToMol(fName, true, false); TEST_ASSERT(m); Conformer &conf = m->getConformer(); double dist = getBondLength(conf, 0, 19); TEST_ASSERT(RDKit::feq(dist, 1.36)); setBondLength(conf, 0, 19, 2.5); dist = getBondLength(conf, 0, 19); TEST_ASSERT(RDKit::feq(dist, 2.5)); setBondLength(conf, 19, 0, 3.0); dist = getBondLength(conf, 0, 19); TEST_ASSERT(RDKit::feq(dist, 3.0)); }
void kekulizeFused(RWMol &mol, const VECT_INT_VECT ås, unsigned int maxBackTracks) { // get all the atoms in the ring system INT_VECT allAtms; Union(arings, allAtms); // get all the atoms that are candidates to receive a double bond // also mark atoms in the fused system that are not aromatic to begin with // as done. Mark all the bonds that are part of the aromatic system // to be single bonds INT_VECT done; INT_VECT questions; unsigned int nats = mol.getNumAtoms(); unsigned int nbnds = mol.getNumBonds(); boost::dynamic_bitset<> dBndCands(nats); boost::dynamic_bitset<> dBndAdds(nbnds); markDbondCands(mol, allAtms, dBndCands, questions, done); #if 0 std::cerr << "candidates: "; for(int i=0;i<nats;++i) std::cerr << dBndCands[i]; std::cerr << std::endl; #endif bool kekulized; kekulized = kekulizeWorker(mol, allAtms, dBndCands, dBndAdds, done, maxBackTracks); if (!kekulized && questions.size()) { // we failed, but there are some dummy atoms we can try permuting. kekulized = permuteDummiesAndKekulize(mol, allAtms, dBndCands, questions, maxBackTracks); } if (!kekulized) { // we exhausted all option (or crossed the allowed // number of backTracks) and we still need to backtrack // can't kekulize this thing std::ostringstream errout; errout << "Can't kekulize mol."; errout << " Unkekulized atoms:"; for (unsigned int i = 0; i < nats; ++i) { if (dBndCands[i]) errout << " " << i; } errout << std::endl; std::string msg = errout.str(); BOOST_LOG(rdErrorLog) << msg << std::endl; throw MolSanitizeException(msg); } }
void test504() { BOOST_LOG(rdInfoLog) << "-------------------------------------" << std::endl; BOOST_LOG(rdInfoLog) << "Testing FMCS test504" << std::endl; std::cout << "\ntest504()\n"; std::vector<ROMOL_SPTR> mols; const char* smi[] = { // TEST 504 "C(CCNC(C1CC1[c:1]1[c:2]c(Cl)c(Cl)c[c:3]1)=O)CCN1CCC(NC(Nc2ccc(Cl)cc2)=O)" "C1 CHEMBL545864", // - QUERY "FC(F)(F)c1cc(NC(N2CCCN(CCCCCNC(C3CC3c3ccc(Cl)c(Cl)c3)=O)CC2)=O)ccc1Cl " "CHEMBL528228", "FC(F)(F)c1cc(NC(NC2CCN(CCCCCNC(C3CC3c3ccc(Cl)c(Cl)c3)=O)C2)=O)ccc1Cl " "CHEMBL525875", "Fc1ccc(NC(N2CCCN(CCCCCNC(C3CC3c3ccc(Cl)c(Cl)c3)=O)CC2)=O)cc1C(F)(F)F " "CHEMBL527277", "FC(F)(F)c1cc(NC(NC2CCN(CCCCCNC(C3CC3c3ccc(Cl)c(Cl)c3)=O)CC2)=O)ccc1Cl " "CHEMBL537333", "Fc1ccc(NC(NC2CCN(CCCCCNC(C3CC3c3ccc(Cl)c(Cl)c3)=O)C2)=O)cc1C(F)(F)F " "CHEMBL588077", "FC(F)(F)c1ccc(NC(NC2CCN(CCCCCNC(C3CC3c3cc(Cl)c(Cl)cc3)=O)C2)=O)cc1 " "CHEMBL525307", "Fc1ccc(NC(NC2CCN(CCCCCNC(C3CC3c3ccc(Cl)c(Cl)c3)=O)CC2)=O)cc1C(F)(F)F " "CHEMBL581847", "FC(F)(F)c1ccc(NC(NC2CCN(CCCCCNC(C3CC3c3cc(Cl)c(Cl)cc3)=O)CC2)=O)cc1 " "CHEMBL579547", "N#Cc1cccc(NC(NC2CCN(CCCCCNC(C3CC3c3ccc(Cl)c(Cl)c3)=O)CC2)=O)c1 " "CHEMBL529994", }; RWMol* qm = SmilesToMol(getSmilesOnly(smi[0])); unsigned nq = qm->getNumAtoms(); for (size_t ai = 0; ai < nq; ai++) { Atom* atom = qm->getAtomWithIdx(ai); atom->setProp("molAtomMapNumber", (int)ai); } std::cout << "Query +MAP " << MolToSmiles(*qm) << "\n"; mols.push_back(ROMOL_SPTR(qm)); // with RING INFO for (size_t i = 1; i < sizeof(smi) / sizeof(smi[0]); i++) mols.push_back( ROMOL_SPTR(SmilesToMol(getSmilesOnly(smi[i])))); // with RING INFO t0 = nanoClock(); MCSResult res = findMCS(mols); std::cout << "MCS: " << res.SmartsString << " " << res.NumAtoms << " atoms, " << res.NumBonds << " bonds\n"; printTime(); TEST_ASSERT(res.NumAtoms == 34 && res.NumBonds == 36); BOOST_LOG(rdInfoLog) << "\tdone" << std::endl; }
// Test the following GitHub issue: https://github.com/rdkit/rdkit/issues/114 void testIssue114(std::string rdbase) { BOOST_LOG(rdInfoLog) << "-----------------------------------" << std::endl; BOOST_LOG(rdInfoLog) << "-- testing GitHub issue #114 --" << std::endl; BOOST_LOG(rdInfoLog) << "-----------------------------------" << std::endl; std::string fName = rdbase + "/Code/GraphMol/FileParsers/test_data/EZ_mol2_issue114.mol2"; RWMol *mol = Mol2FileToMol(fName); TEST_ASSERT(mol); TEST_ASSERT(mol->getBondWithIdx(1)->getStereo() == Bond::STEREOZ); delete mol; BOOST_LOG(rdInfoLog) << "------------------------------------" << std::endl; BOOST_LOG(rdInfoLog) << "-- DONE --" << std::endl; BOOST_LOG(rdInfoLog) << "------------------------------------" << std::endl; }
void testGetSetAngle() { std::string rdbase = getenv("RDBASE"); std::string fName = rdbase + "/Code/GraphMol/MolTransforms/test_data/3-cyclohexylpyridine.mol"; RWMol *m = MolFileToMol(fName, true, false); TEST_ASSERT(m); Conformer &conf = m->getConformer(); double angle = getAngleDeg(conf, 0, 19, 21); TEST_ASSERT(RDKit::feq(RDKit::round(angle * 10) / 10, 109.7)); setAngleDeg(conf, 0, 19, 21, 125.0); angle = getAngleDeg(conf, 0, 19, 21); TEST_ASSERT(RDKit::feq(angle, 125.0)); setAngleRad(conf, 21, 19, 0, M_PI / 2.); angle = getAngleRad(conf, 0, 19, 21); TEST_ASSERT(RDKit::feq(angle, M_PI / 2.)); angle = getAngleDeg(conf, 0, 19, 21); TEST_ASSERT(RDKit::feq(angle, 90.0)); }
void testGithub186(){ BOOST_LOG(rdInfoLog) << "testing github issue 186: chiral S not written to ctab" << std::endl; std::string rdbase = getenv("RDBASE"); rdbase += "/Code/GraphMol/FileParsers/test_data/"; { std::string fName = rdbase + "github186.mol"; RWMol *m = MolFileToMol(fName); TEST_ASSERT(m); TEST_ASSERT(m->getNumAtoms()==11); TEST_ASSERT(m->getNumBonds()==10); TEST_ASSERT(m->getAtomWithIdx(6)->getChiralTag()!=Atom::CHI_UNSPECIFIED && m->getAtomWithIdx(6)->getChiralTag()!=Atom::CHI_OTHER ); std::string mb=MolToMolBlock(*m); delete m; m = MolBlockToMol(mb); TEST_ASSERT(m); TEST_ASSERT(m->getNumAtoms()==11); TEST_ASSERT(m->getNumBonds()==10); TEST_ASSERT(m->getAtomWithIdx(6)->getChiralTag()!=Atom::CHI_UNSPECIFIED && m->getAtomWithIdx(6)->getChiralTag()!=Atom::CHI_OTHER ); delete m; } }
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 AddMWMF(RWMol &mol, bool pre) { // set formula & mass properties "MW_PRE" "MW_POST" double mass = 0.0; mass = RDKit::Descriptors::calcExactMW(mol); /* for (unsigned i = 0; i < mol.getNumAtoms(); i++) { const Atom& atom = *mol.getAtomWithIdx(i); mass += atom.getMass(); mass += atom.getNumImplicitHs() * 1.0080; // and add implicit Hydrogens mass } */ std::string formula = getMolecularFormula(mol); if (!formula.empty()) mol.setProp((pre ? "MF_PRE" : "MF_POST"), formula); char propertyValue[64]; snprintf(propertyValue, sizeof(propertyValue), "%g", mass); mol.setProp((pre ? "MW_PRE" : "MW_POST"), mass); }
bool permuteDummiesAndKekulize(RWMol &mol, const INT_VECT &allAtms, boost::dynamic_bitset<> dBndCands, INT_VECT &questions, unsigned int maxBackTracks) { boost::dynamic_bitset<> atomsInPlay(mol.getNumAtoms()); for (int allAtm : allAtms) { atomsInPlay[allAtm] = 1; } bool kekulized = false; QuestionEnumerator qEnum(questions); while (!kekulized && questions.size()) { boost::dynamic_bitset<> dBndAdds(mol.getNumBonds()); INT_VECT done; #if 1 // reset the state: all aromatic bonds are remarked to single: for (RWMol::BondIterator bi = mol.beginBonds(); bi != mol.endBonds(); ++bi) { if ((*bi)->getIsAromatic() && (*bi)->getBondType() != Bond::SINGLE && atomsInPlay[(*bi)->getBeginAtomIdx()] && atomsInPlay[(*bi)->getEndAtomIdx()]) { (*bi)->setBondType(Bond::SINGLE); } } #endif // pick a new permutation of the questionable atoms: const INT_VECT &switchOff = qEnum.next(); if (!switchOff.size()) break; boost::dynamic_bitset<> tCands = dBndCands; for (int it : switchOff) { tCands[it] = 0; } #if 0 std::cerr<<"permute: "; for (boost::dynamic_bitset<>::size_type i = 0; i < tCands.size(); ++i){ std::cerr << tCands[i]; } std::cerr<<std::endl; #endif // try kekulizing again: kekulized = kekulizeWorker(mol, allAtms, tCands, dBndAdds, done, maxBackTracks); } return kekulized; }
void testSFIssue1653802(){ BOOST_LOG(rdErrorLog) << "-------------------------------------" << std::endl; BOOST_LOG(rdErrorLog) << " Testing SFIssue1653802." << std::endl; RWMol *mol; int needMore; ForceFields::ForceField *field; std::string pathName=getenv("RDBASE"); pathName += "/Code/GraphMol/ForceFieldHelpers/UFF/test_data"; mol = MolFileToMol(pathName+"/cyclobutadiene.mol",false); TEST_ASSERT(mol); MolOps::sanitizeMol(*mol); UFF::AtomicParamVect types; bool foundAll; boost::shared_array<boost::uint8_t> nbrMat; boost::tie(types,foundAll)=UFF::getAtomTypes(*mol); TEST_ASSERT(foundAll); TEST_ASSERT(types.size()==mol->getNumAtoms()); field=new ForceFields::ForceField(); UFF::Tools::addBonds(*mol,types,field); TEST_ASSERT(field->contribs().size()==8); nbrMat = UFF::Tools::buildNeighborMatrix(*mol); UFF::Tools::addAngles(*mol,types,field); TEST_ASSERT(field->contribs().size()==20); UFF::Tools::addTorsions(*mol,types,field); //std::cout << field->contribs().size() << std::endl; TEST_ASSERT(field->contribs().size()==36); UFF::Tools::addNonbonded(*mol,0,types,field,nbrMat); delete field; field = UFF::constructForceField(*mol); field->initialize(); needMore = field->minimize(200,1e-6,1e-3); TEST_ASSERT(!needMore); delete mol; delete field; BOOST_LOG(rdErrorLog) << " done" << std::endl; }
void test2() { BOOST_LOG(rdInfoLog) << "testing coordinate generation" << std::endl; #if 1 { RWMol *m = SmilesToMol("c1cccnc1"); TEST_ASSERT(m); unsigned int confId = AvalonTools::set2DCoords(*m); TEST_ASSERT(m->getNumConformers() == 1); TEST_ASSERT(confId == 0); delete m; } #endif { std::string molb = AvalonTools::set2DCoords("c1cccnc1", true); TEST_ASSERT(molb != ""); } BOOST_LOG(rdInfoLog) << "done" << std::endl; }
void testGetSetDihedral() { std::string rdbase = getenv("RDBASE"); std::string fName = rdbase + "/Code/GraphMol/MolTransforms/test_data/3-cyclohexylpyridine.mol"; RWMol *m = MolFileToMol(fName, true, false); TEST_ASSERT(m); Conformer &conf = m->getConformer(); double dihedral = getDihedralDeg(conf, 0, 19, 21, 24); TEST_ASSERT(RDKit::feq(RDKit::round(dihedral * 100) / 100, 176.05)); setDihedralDeg(conf, 8, 0, 19, 21, 65.0); dihedral = getDihedralDeg(conf, 8, 0, 19, 21); TEST_ASSERT(RDKit::feq(dihedral, 65.0)); setDihedralDeg(conf, 8, 0, 19, 21, -130.0); dihedral = getDihedralDeg(conf, 8, 0, 19, 21); TEST_ASSERT(RDKit::feq(dihedral, -130.0)); setDihedralRad(conf, 21, 19, 0, 8, -2. / 3. * M_PI); dihedral = getDihedralRad(conf, 8, 0, 19, 21); TEST_ASSERT(RDKit::feq(dihedral, -2. / 3. * M_PI)); dihedral = getDihedralDeg(conf, 8, 0, 19, 21); TEST_ASSERT(RDKit::feq(dihedral, -120.0)); }
int main(int argc, char *argv[]) { RDLog::InitLogs(); std::string fname; if (argc > 1) { fname = argv[1]; } else { BOOST_LOG(rdErrorLog) << "Pass in the list of smiles\n"; } std::ifstream inStream(fname.c_str()); const int MAX_LINE_LEN = 256; char inLine[MAX_LINE_LEN]; std::string tmpstr; std::string smi; inStream.getline(inLine, MAX_LINE_LEN, '\n'); tmpstr = inLine; // MolOps molop; while (tmpstr.size() > 0) { getSmiles(tmpstr, smi); RWMol *m = SmilesToMol(smi, 0, 0); try { // testKekule(*m); MolOps::sanitizeMol(*m); int nar; m->getProp(common_properties::numArom, nar); BOOST_LOG(rdInfoLog) << nar << "\n"; // MolOps::setHybridization(*m); delete m; } catch (MolSanitizeException) { BOOST_LOG(rdErrorLog) << smi << "\n"; delete m; } inStream.getline(inLine, MAX_LINE_LEN, '\n'); tmpstr = inLine; } return 1; }
void test1(){ #ifdef SUPPORT_COMPRESSED_IO BOOST_LOG(rdInfoLog) << "testing basic reading from compressed streams" << std::endl; std::string rdbase = getenv("RDBASE"); std::string fname2 = rdbase + "/Code/Demos/RDKit/BinaryIO/test_data/triazine.mol.gz"; RWMol *m; io::filtering_istream inStrm; inStrm.push(io::gzip_decompressor()); inStrm.push(io::file_source(fname2)); TEST_ASSERT(inStrm.is_complete()); unsigned int lineNo=0; m = MolDataStreamToMol(inStrm,lineNo); TEST_ASSERT(m); TEST_ASSERT(m->getNumAtoms(6)); BOOST_LOG(rdInfoLog) << "done" << std::endl; #else BOOST_LOG(rdInfoLog) << "Compressed IO disabled; test skipped" << std::endl; #endif }
void test2() { #ifdef SUPPORT_COMPRESSED_IO BOOST_LOG(rdInfoLog) << "testing writing to, then reading from compressed streams" << std::endl; std::string smiles = "C1CCCC1"; std::string buff, molBlock; RWMol *m; m = SmilesToMol(smiles); TEST_ASSERT(m); TEST_ASSERT(m->getNumAtoms(5)); m->setProp(common_properties::_Name, "monkey"); io::filtering_ostream outStrm; outStrm.push(io::gzip_compressor()); outStrm.push(io::back_inserter(buff)); TEST_ASSERT(outStrm.is_complete()); molBlock = MolToMolBlock(*m); outStrm << molBlock; outStrm.reset(); delete m; io::filtering_istream inStrm; inStrm.push(io::gzip_decompressor()); inStrm.push(boost::make_iterator_range(buff)); TEST_ASSERT(inStrm.is_complete()); unsigned int lineNo = 0; m = MolDataStreamToMol(inStrm, lineNo); TEST_ASSERT(m); TEST_ASSERT(m->getNumAtoms(5)); BOOST_LOG(rdInfoLog) << "done" << std::endl; #else BOOST_LOG(rdInfoLog) << "Compressed IO disabled; test skipped" << std::endl; #endif }
void test18() { BOOST_LOG(rdInfoLog) << "-------------------------------------" << std::endl; BOOST_LOG(rdInfoLog) << "Testing FMCS test18" << std::endl; std::cout << "\ntest18()\n"; std::vector<ROMOL_SPTR> mols; const char* smi[] = { // TEST 18 "Cc1nc(CN(C(C)c2ncccc2)CCCCN)ccc1 CHEMBL1682991", //-- QUERY "Cc1ccc(CN(C(C)c2ccccn2)CCCCN)nc1 CHEMBL1682990", "Cc1cccnc1CN(C(C)c1ccccn1)CCCCN CHEMBL1682998", "CC(N(CCCCN)Cc1c(N)cccn1)c1ccccn1 CHEMBL1682987", "Cc1cc(C)c(CN(C(C)c2ccccn2)CCCCN)nc1 CHEMBL1682992", "Cc1cc(C(C)N(CCCCN)Cc2c(C)cccn2)ncc1 CHEMBL1682993", "Cc1nc(C(C)N(CCCCN)Cc2nc3c([nH]2)cccc3)ccc1 CHEMBL1682878", "CC(c1ncccc1)N(CCCCN)Cc1nc2c([nH]1)cccc2 CHEMBL1682867", "CC(N(CCCCN)Cc1c(C(C)(C)C)cccn1)c1ccccn1 CHEMBL1682989", "CC(N(CCCCN)Cc1c(C(F)(F)F)cccn1)c1ccccn1 CHEMBL1682988", //# 18 . 20 20 0.04 sec. Python MCS: CC(c1ccccn1)N(CCCCN)Ccnccc }; RWMol* qm = SmilesToMol(getSmilesOnly(smi[0])); unsigned nq = qm->getNumAtoms(); for (size_t ai = 0; ai < nq; ai++) { Atom* atom = qm->getAtomWithIdx(ai); atom->setProp("molAtomMapNumber", (int)ai); } std::cout << "Query +MAP " << MolToSmiles(*qm) << "\n"; mols.push_back(ROMOL_SPTR(qm)); // with RING INFO for (size_t i = 1; i < sizeof(smi) / sizeof(smi[0]); i++) mols.push_back( ROMOL_SPTR(SmilesToMol(getSmilesOnly(smi[i])))); // with RING INFO t0 = nanoClock(); MCSResult res = findMCS(mols); std::cout << "MCS: " << res.SmartsString << " " << res.NumAtoms << " atoms, " << res.NumBonds << " bonds\n"; printTime(); TEST_ASSERT(res.NumAtoms == 21 && res.NumBonds == 21); BOOST_LOG(rdInfoLog) << "\tdone" << std::endl; }
void test1ConstructGrid() { std::string path = getenv("RDBASE"); path += "/Code/GraphMol/MIF/test_data/"; // //Generate Molecule with 3D Coordinates and Partial Charges // RWMol mol=*SmilesToMol("Cl"); // MolOps::addHs(mol); // DGeomHelpers::EmbedMolecule(mol); // MolToMolFile(mol, path + "HCl.mol"); RWMol mol = *MolFileToMol(path + "HCl.mol", true, false); UniformRealValueGrid3D grd = *constructGrid(mol, 0, 5.0, 0.5); Point3D bond = mol.getConformer().getAtomPos(1) - mol.getConformer().getAtomPos(0); CHECK_INVARIANT(feq(grd.getSpacing (), 0.5), "Spacing of grid is not correct."); CHECK_INVARIANT(feq(grd.getNumX (), std::floor ((fabs (bond.x) + 10.0) / 0.5 + 0.5)), "X length of grid is incorrect."); CHECK_INVARIANT(feq(grd.getNumY (), std::floor ((fabs (bond.y) + 10.0) / 0.5 + 0.5)), "Y length of grid is incorrect."); CHECK_INVARIANT(feq(grd.getNumZ (), std::floor ((fabs (bond.z) + 10.0) / 0.5 + 0.5)), "Z length of grid is incorrect."); }
ROMol *fragmentOnBonds( const ROMol &mol, const std::vector<unsigned int> &bondIndices, bool addDummies, const std::vector<std::pair<unsigned int, unsigned int> > *dummyLabels, const std::vector<Bond::BondType> *bondTypes, std::vector<unsigned int> *nCutsPerAtom) { PRECONDITION((!dummyLabels || dummyLabels->size() == bondIndices.size()), "bad dummyLabel vector"); PRECONDITION((!bondTypes || bondTypes->size() == bondIndices.size()), "bad bondType vector"); PRECONDITION((!nCutsPerAtom || nCutsPerAtom->size() == mol.getNumAtoms()), "bad nCutsPerAtom vector"); if (nCutsPerAtom) { BOOST_FOREACH (unsigned int &nCuts, *nCutsPerAtom) { nCuts = 0; } } RWMol *res = new RWMol(mol); if (!mol.getNumAtoms()) return res; std::vector<Bond *> bondsToRemove; bondsToRemove.reserve(bondIndices.size()); BOOST_FOREACH (unsigned int bondIdx, bondIndices) { bondsToRemove.push_back(res->getBondWithIdx(bondIdx)); }