//************************************************************************************* // // 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 test6() { BOOST_LOG(rdErrorLog) << "-------------------------------------" << std::endl; BOOST_LOG(rdErrorLog) << "Feature Location testing." << std::endl; ROMol *testMol; Conformer *conf; std::string inText; FeatSPtrList featSPtrs; boost::shared_ptr<MolChemicalFeature> featSPtr; MolChemicalFeatureFactory *factory; MolChemicalFeatureDef::CollectionType::value_type featDef; inText = "DefineFeature HDonor1 [N,O;!H0]\n" " Family HBondDonor\n" " Weights 1.0\n" "EndFeature\n" "DefineFeature Carboxyl1 C(=O)[O;H1,-]\n" " Family ZnBinder\n" " Weights 1.0,1.0,1.0\n" "EndFeature\n"; factory = buildFeatureFactory(inText); TEST_ASSERT(factory); TEST_ASSERT(factory->getNumFeatureDefs() == 2); testMol = SmilesToMol("C(=O)O"); TEST_ASSERT(testMol); conf = new Conformer(3); testMol->addConformer(conf); conf->setAtomPos(0, RDGeom::Point3D(0, 0, 0.0)); conf->setAtomPos(1, RDGeom::Point3D(1.2, 0, 0.0)); conf->setAtomPos(2, RDGeom::Point3D(0, 1.5, 0.0)); featSPtrs = factory->getFeaturesForMol(*testMol); TEST_ASSERT(featSPtrs.size() == 2); featSPtr = *featSPtrs.begin(); TEST_ASSERT(featSPtr->getFamily() == "HBondDonor"); TEST_ASSERT(featSPtr->getType() == "HDonor1"); TEST_ASSERT(feq(featSPtr->getPos().x, 0.0)); TEST_ASSERT(feq(featSPtr->getPos().y, 1.5)); TEST_ASSERT(feq(featSPtr->getPos().z, 0.0)); featSPtr = *(++featSPtrs.begin()); TEST_ASSERT(featSPtr->getFamily() == "ZnBinder"); TEST_ASSERT(featSPtr->getType() == "Carboxyl1"); TEST_ASSERT(feq(featSPtr->getPos().x, 0.4)); TEST_ASSERT(feq(featSPtr->getPos().y, 0.5)); TEST_ASSERT(feq(featSPtr->getPos().z, 0.0)); delete testMol; delete factory; BOOST_LOG(rdErrorLog) << " done" << std::endl; }
void testConformerCopying() { BOOST_LOG(rdInfoLog) << "-----------------------\n Testing copying conformers" << std::endl; { std::string smi = "CCC"; ROMol *m = static_cast<ROMol *>(SmilesToMol(smi)); TEST_ASSERT(m); auto *conf = new Conformer(m->getNumAtoms()); conf->setId(1); m->addConformer(conf, false); conf = new Conformer(m->getNumAtoms()); conf->setId(2); m->addConformer(conf, false); { auto *m2 = new ROMol(*m); TEST_ASSERT(m2->getNumConformers() == 2); delete m2; } { auto *m2 = new ROMol(*m, false, 1); TEST_ASSERT(m2->getNumConformers() == 1); TEST_ASSERT(m2->getConformer().getId() == 1); delete m2; } { auto *m2 = new ROMol(*m, false, 2); TEST_ASSERT(m2->getNumConformers() == 1); TEST_ASSERT(m2->getConformer().getId() == 2); delete m2; } { auto *m2 = new ROMol(*m, false, 3); TEST_ASSERT(m2->getNumConformers() == 0); delete m2; } delete m; } BOOST_LOG(rdInfoLog) << "Finished" << std::endl; }
void testMMFFMultiThread2() { BOOST_LOG(rdErrorLog) << "-------------------------------------" << std::endl; BOOST_LOG(rdErrorLog) << " Test MMFF multithreading2" << std::endl; std::string pathName = getenv("RDBASE"); pathName += "/Code/GraphMol/ForceFieldHelpers/UFF/test_data"; SDMolSupplier suppl(pathName + "/bulk.sdf"); ROMol *m = suppl[4]; TEST_ASSERT(m); ROMol *om = new ROMol(*m); for (unsigned int i = 0; i < 1000; ++i) { m->addConformer(new Conformer(m->getConformer()), true); } std::vector<std::pair<int, double> > res; MMFF::MMFFOptimizeMolecule(*om); MMFF::MMFFOptimizeMoleculeConfs(*m, res, 0); for (unsigned int i = 1; i < res.size(); ++i) { TEST_ASSERT(!res[i].first); TEST_ASSERT(feq(res[i].second, res[0].second, .00001)); } for (unsigned int i = 0; i < m->getNumAtoms(); ++i) { RDGeom::Point3D p0 = om->getConformer().getAtomPos(i); RDGeom::Point3D np0 = m->getConformer().getAtomPos(i); TEST_ASSERT(feq(p0.x, np0.x)); TEST_ASSERT(feq(p0.y, np0.y)); TEST_ASSERT(feq(p0.z, np0.z)); np0 = m->getConformer(11).getAtomPos(i); // pick some random other conformer TEST_ASSERT(feq(p0.x, np0.x)); TEST_ASSERT(feq(p0.y, np0.y)); TEST_ASSERT(feq(p0.z, np0.z)); } delete m; delete om; BOOST_LOG(rdErrorLog) << " done" << std::endl; }
void test1Canonicalization() { ROMol *mol = SmilesToMol("C", 0, 1); Conformer *conf = new Conformer(1); conf->setAtomPos(0, RDGeom::Point3D(4.0, 5.0, 6.0)); int cid = mol->addConformer(conf, true); RDGeom::Point3D pt = computeCentroid(*conf); CHECK_INVARIANT(comparePts(pt, RDGeom::Point3D(4.0, 5.0, 6.0)), ""); RDGeom::Transform3D *trans = computeCanonicalTransform(*conf); transformConformer(*conf, *trans); CHECK_INVARIANT(comparePts(conf->getAtomPos(0), RDGeom::Point3D(0.0, 0.0, 0.0)), ""); conf->setAtomPos(0, RDGeom::Point3D(4.0, 5.0, 6.0)); canonicalizeConformer(*conf); CHECK_INVARIANT(comparePts(conf->getAtomPos(0), RDGeom::Point3D(0.0, 0.0, 0.0)), ""); delete mol; //delete conf; delete trans; // lets try two points now mol = SmilesToMol("CC", 0, 1); conf = new Conformer(2); conf->setAtomPos(0, RDGeom::Point3D(0.0, 0.0, 0.0)); conf->setAtomPos(1, RDGeom::Point3D(1.5, 0.0, 0.0)); cid = mol->addConformer(conf, true); trans = computeCanonicalTransform(*conf); canonicalizeConformer(*conf); CHECK_INVARIANT(comparePts(conf->getAtomPos(0), RDGeom::Point3D(-0.75, 0.0, 0.0)), ""); CHECK_INVARIANT(comparePts(conf->getAtomPos(1), RDGeom::Point3D(0.75, 0.0, 0.0)), ""); conf->setAtomPos(0, RDGeom::Point3D(0.0, 0.0, 0.0)); conf->setAtomPos(1, RDGeom::Point3D(0.0, 1.5, 0.0)); trans = computeCanonicalTransform(*conf); canonicalizeConformer(*conf); CHECK_INVARIANT(comparePts(conf->getAtomPos(0), RDGeom::Point3D(-0.75, 0.0, 0.0)), ""); CHECK_INVARIANT(comparePts(conf->getAtomPos(1), RDGeom::Point3D(0.75, 0.0, 0.0)), ""); delete mol; delete trans; mol = SmilesToMol("CC", 0, 1); conf = new Conformer(2); conf->setAtomPos(0, RDGeom::Point3D(0.0, 0.0, 0.0)); conf->setAtomPos(1, RDGeom::Point3D(1.5, 0.0, 0.0)); cid = mol->addConformer(conf, true); trans = computeCanonicalTransform(*conf); transformConformer(*conf, *trans); canonicalizeConformer(*conf); CHECK_INVARIANT(comparePts(conf->getAtomPos(0), RDGeom::Point3D(-0.75, 0.0, 0.0)), ""); CHECK_INVARIANT(comparePts(conf->getAtomPos(1), RDGeom::Point3D(0.75, 0.0, 0.0)), ""); delete mol; delete trans; mol = SmilesToMol("C1CC1", 0, 1); conf = new Conformer(3); conf->setAtomPos(0, RDGeom::Point3D(0.58, -0.66, -0.08)); conf->setAtomPos(1, RDGeom::Point3D(-0.88, -0.18, -0.04)); conf->setAtomPos(2, RDGeom::Point3D(.26, 0.82, 0.14)); cid = mol->addConformer(conf, true); //trans = computeCanonicalTransform(*conf); //transformConformer(*conf, *trans); canonicalizeConformer(*conf); CHECK_INVARIANT(comparePts(conf->getAtomPos(0), RDGeom::Point3D(-0.6418, 0.6158, 0.0)), ""); CHECK_INVARIANT(comparePts(conf->getAtomPos(1), RDGeom::Point3D(-0.2029, -0.8602, 0.0)), ""); CHECK_INVARIANT(comparePts(conf->getAtomPos(2), RDGeom::Point3D(0.8447, 0.2445, 0.0)), ""); MolToMolFile(*mol, "junk.mol", 0); //CHECK_INVARIANT(comparePts(conf->getAtomPos(0), RDGeom::Point3D(-0.75, 0.0, 0.0)), ""); //CHECK_INVARIANT(comparePts(conf->getAtomPos(1), RDGeom::Point3D(0.75, 0.0, 0.0)), ""); delete mol; std::string rdbase = getenv("RDBASE"); std::string fname1 = rdbase + "/Code/GraphMol/MolTransforms/test_data/1oir.mol"; mol = MolFileToMol(fname1); std::string fname2 = rdbase + "/Code/GraphMol/MolTransforms/test_data/1oir_canon.mol"; ROMol *mol2 = MolFileToMol(fname2); Conformer &conf1 = mol->getConformer(0); canonicalizeConformer(conf1); Conformer &conf2 = mol2->getConformer(); unsigned int i, nats = mol->getNumAtoms(); for (i = 0; i < nats; ++i) { CHECK_INVARIANT(comparePts(conf1.getAtomPos(i), conf2.getAtomPos(i)), ""); } delete mol; delete mol2; }
ROMol *TDTMolSupplier::parseMol(std::string inLine){ PRECONDITION(dp_inStream,"no stream"); Utils::LocaleSwitcher ls; std::size_t startP=inLine.find("<"); std::size_t endP=inLine.find_last_of(">"); std::string smiles = inLine.substr(startP+1,endP-startP-1); ROMol *res = SmilesToMol(smiles,0,df_sanitize); if(res && res->getNumAtoms()>0){ // ----------- // Process the properties: d_line++; std::getline(*dp_inStream,inLine); while(!dp_inStream->eof() && inLine.find("|")!=0){ endP=inLine.find("<"); std::string propName = inLine.substr(0,endP); boost::trim_if(propName,boost::is_any_of(" \t")); startP = endP+1; if(propName=="2D" && d_confId2D>=0){ std::string rest=inLine.substr(startP,inLine.size()-startP); std::vector<double> coords; TDTParseUtils::ParseNumberList(rest,coords,dp_inStream); Conformer *conf=new Conformer(res->getNumAtoms()); conf->setId(d_confId2D); conf->set3D(false); for(unsigned int atIdx=0;atIdx<res->getNumAtoms();atIdx++){ if(2*atIdx+1 < coords.size()){ conf->setAtomPos(atIdx,RDGeom::Point3D(coords[2*atIdx],coords[2*atIdx+1],0.0)); } else { // we're going to let this slide... but maybe we should do something else? } } res->addConformer(conf,false); } else if(propName=="3D" && d_confId3D>=0){ std::string rest=inLine.substr(startP,inLine.size()-startP); std::vector<double> coords; TDTParseUtils::ParseNumberList(rest,coords,dp_inStream); Conformer *conf=new Conformer(res->getNumAtoms()); conf->setId(d_confId3D); conf->set3D(true); for(unsigned int atIdx=0;atIdx<res->getNumAtoms();atIdx++){ if(3*atIdx+2 < coords.size()){ conf->setAtomPos(atIdx,RDGeom::Point3D(coords[3*atIdx], coords[3*atIdx+1], coords[3*atIdx+2])); } else { // we're going to let this slide... but maybe we should do something else? } } res->addConformer(conf,false); } else { endP=inLine.find_last_of(">"); if(endP==std::string::npos){ std::ostringstream errout; errout << "no end tag found for property" << propName; throw FileParseException(errout.str()); } else { std::string propVal = inLine.substr(startP,endP-startP); res->setProp(propName,propVal); if(propName==d_nameProp) res->setProp("_Name",propVal); } } std::getline(*dp_inStream,inLine); } } return res; }