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; }
FeatSPtr getMolFeature(const MolChemicalFeatureFactory &factory, const ROMol &mol, int idx, std::string includeOnly = "", bool recompute = true) { static FeatSPtrList feats; if (recompute) { feats = factory.getFeaturesForMol(mol, includeOnly.c_str()); } if (idx < 0 || idx >= static_cast<int>(feats.size())) { throw IndexErrorException(idx); } FeatSPtrList_I fi = feats.begin(); for (int i = 0; i < idx; ++i) { ++fi; } return (*fi); }
void testGithub252() { BOOST_LOG(rdErrorLog) << "-------------------------------------" << std::endl; BOOST_LOG(rdErrorLog) << "Testing Github Issue #252: crash when calling " "getPos() with no conformer." << std::endl; BOOST_LOG(rdErrorLog) << " expect a precondition failure message below" << std::endl; ROMol *testMol; MolChemicalFeatureFactory *factory; FeatSPtrList featSPtrs; boost::shared_ptr<MolChemicalFeature> featSPtr; std::string fdef = "DefineFeature CTriplet [C][C][C]\n" " Family LumpedHydrophobe\n" " Weights 1.0,1.0,1.0\n" "EndFeature\n" "DefineFeature CPair [C][C]\n" " Family LumpedHydrophobe\n" " Weights 1.0,1.0\n" "EndFeature\n"; factory = buildFeatureFactory(fdef); TEST_ASSERT(factory); TEST_ASSERT(factory->getNumFeatureDefs() == 2); testMol = SmilesToMol("CCC"); TEST_ASSERT(testMol); featSPtrs = factory->getFeaturesForMol(*testMol); TEST_ASSERT(featSPtrs.size() == 1); featSPtr = *featSPtrs.begin(); TEST_ASSERT(featSPtr->getFamily() == "LumpedHydrophobe"); bool ok = false; try { featSPtr->getPos(); } catch (const Invar::Invariant &) { ok = true; } delete factory; delete testMol; TEST_ASSERT(ok); BOOST_LOG(rdErrorLog) << " Done" << std::endl; }
void testIssue347() { BOOST_LOG(rdErrorLog) << "-------------------------------------" << std::endl; BOOST_LOG(rdErrorLog) << "Test Issue347" << std::endl; ROMol *testMol; MolChemicalFeatureFactory *factory; MolChemicalFeatureDef::CollectionType::const_iterator featDefIt; MolChemicalFeatureDef::CollectionType::value_type featDef; FeatSPtrList featSPtrs; boost::shared_ptr<MolChemicalFeature> featSPtr; std::string fdef; fdef = "DefineFeature CTriplet [C][C][C]\n" " Family LumpedHydrophobe\n" " Weights 1.0,1.0,1.0\n" "EndFeature\n" "DefineFeature CPair [C][C]\n" " Family LumpedHydrophobe\n" " Weights 1.0,1.0\n" "EndFeature\n"; factory = buildFeatureFactory(fdef); TEST_ASSERT(factory); TEST_ASSERT(factory->getNumFeatureDefs() == 2); featDefIt = factory->beginFeatureDefs(); featDef = *featDefIt; TEST_ASSERT(featDef->getFamily() == "LumpedHydrophobe"); featDefIt++; featDef = *featDefIt; TEST_ASSERT(featDef->getFamily() == "LumpedHydrophobe"); featDefIt++; TEST_ASSERT(featDefIt == factory->endFeatureDefs()); testMol = SmilesToMol("CCC"); TEST_ASSERT(testMol); featSPtrs = factory->getFeaturesForMol(*testMol); TEST_ASSERT(featSPtrs.size() == 1); featSPtr = *featSPtrs.begin(); TEST_ASSERT(featSPtr->getFamily() == "LumpedHydrophobe"); TEST_ASSERT(featSPtr->getType() == "CTriplet"); delete factory; // now reverse the order and we should get two matches: fdef = "DefineFeature CPair [C][C]\n" " Family LumpedHydrophobe\n" " Weights 1.0,1.0\n" "EndFeature\n" "DefineFeature CTriplet [C][C][C]\n" " Family LumpedHydrophobe\n" " Weights 1.0,1.0,1.0\n" "EndFeature\n"; factory = buildFeatureFactory(fdef); TEST_ASSERT(factory); TEST_ASSERT(factory->getNumFeatureDefs() == 2); featDefIt = factory->beginFeatureDefs(); featDef = *featDefIt; TEST_ASSERT(featDef->getFamily() == "LumpedHydrophobe"); featDefIt++; featDef = *featDefIt; TEST_ASSERT(featDef->getFamily() == "LumpedHydrophobe"); featDefIt++; TEST_ASSERT(featDefIt == factory->endFeatureDefs()); featSPtrs = factory->getFeaturesForMol(*testMol); TEST_ASSERT(featSPtrs.size() == 3); featSPtr = *featSPtrs.begin(); TEST_ASSERT(featSPtr->getFamily() == "LumpedHydrophobe"); TEST_ASSERT(featSPtr->getType() == "CPair"); featSPtr = *(++featSPtrs.begin()); TEST_ASSERT(featSPtr->getFamily() == "LumpedHydrophobe"); TEST_ASSERT(featSPtr->getType() == "CPair"); featSPtr = *(++++featSPtrs.begin()); TEST_ASSERT(featSPtr->getFamily() == "LumpedHydrophobe"); TEST_ASSERT(featSPtr->getType() == "CTriplet"); delete factory; delete testMol; BOOST_LOG(rdErrorLog) << " done" << std::endl; }
void test5() { BOOST_LOG(rdErrorLog) << "-------------------------------------" << std::endl; BOOST_LOG(rdErrorLog) << "FeatureFactory testing." << std::endl; ROMol *testMol; MatchVectType mv; 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 HAcceptor1 [N,O]\n" " Family HBondAcceptor\n" " Weights 1.0\n" "EndFeature\n"; factory = buildFeatureFactory(inText); TEST_ASSERT(factory); TEST_ASSERT(factory->getNumFeatureDefs() == 2); testMol = SmilesToMol("COCN"); TEST_ASSERT(testMol); featDef = *factory->beginFeatureDefs(); TEST_ASSERT(SubstructMatch(*testMol, *featDef->getPattern(), mv)); BOOST_LOG(rdErrorLog) << "1" << std::endl; TEST_ASSERT(mv.size() == 1); TEST_ASSERT(mv[0].first == 0); TEST_ASSERT(mv[0].second == 3); featDef = *(++factory->beginFeatureDefs()); TEST_ASSERT(SubstructMatch(*testMol, *featDef->getPattern(), mv)); BOOST_LOG(rdErrorLog) << "2" << std::endl; TEST_ASSERT(mv.size() == 1); TEST_ASSERT(mv[0].first == 0); TEST_ASSERT(mv[0].second == 1 || mv[0].second == 3); // Test using the factory to find features: featSPtrs = factory->getFeaturesForMol(*testMol); BOOST_LOG(rdErrorLog) << "3" << std::endl; TEST_ASSERT(featSPtrs.size() == 3); featSPtr = *featSPtrs.begin(); TEST_ASSERT(featSPtr->getFamily() == "HBondDonor"); TEST_ASSERT(featSPtr->getType() == "HDonor1"); featSPtr = *(++featSPtrs.begin()); TEST_ASSERT(featSPtr->getFamily() == "HBondAcceptor"); TEST_ASSERT(featSPtr->getType() == "HAcceptor1"); featSPtr = *(++featSPtrs.begin()); TEST_ASSERT(featSPtr->getFamily() == "HBondAcceptor"); TEST_ASSERT(featSPtr->getType() == "HAcceptor1"); // Test limiting stuff with includeOnly featSPtrs = factory->getFeaturesForMol(*testMol, "HBondAcceptor"); BOOST_LOG(rdErrorLog) << "4" << std::endl; TEST_ASSERT(featSPtrs.size() == 2); featSPtr = *featSPtrs.begin(); TEST_ASSERT(featSPtr->getFamily() == "HBondAcceptor"); TEST_ASSERT(featSPtr->getType() == "HAcceptor1"); featSPtr = *(++featSPtrs.begin()); TEST_ASSERT(featSPtr->getFamily() == "HBondAcceptor"); TEST_ASSERT(featSPtr->getType() == "HAcceptor1"); featSPtrs = factory->getFeaturesForMol(*testMol, "HBondDonor"); BOOST_LOG(rdErrorLog) << "5" << std::endl; TEST_ASSERT(featSPtrs.size() == 1); featSPtr = *featSPtrs.begin(); TEST_ASSERT(featSPtr->getFamily() == "HBondDonor"); TEST_ASSERT(featSPtr->getType() == "HDonor1"); featSPtrs = factory->getFeaturesForMol(*testMol, "NotPresent"); BOOST_LOG(rdErrorLog) << "6" << std::endl; TEST_ASSERT(featSPtrs.size() == 0); delete testMol; delete factory; BOOST_LOG(rdErrorLog) << " done" << std::endl; }
int getNumMolFeatures(const MolChemicalFeatureFactory &factory, const ROMol &mol, std::string includeOnly = "") { FeatSPtrList feats = factory.getFeaturesForMol(mol, includeOnly.c_str()); return feats.size(); }
FeatSPtrList MolChemicalFeatureFactory::getFeaturesForMol(const ROMol &mol, const char* includeOnly) const { PRECONDITION(includeOnly,"bad limits"); std::string limits(includeOnly); #ifdef USE_VFLIB AR_MOLGRAPH *molG=getMolGraph(mol); #endif FeatSPtrList res; int idx = 1; typedef std::vector< std::pair< std::string,std::set<int> > > MatchSetCollection; MatchSetCollection matchSets; for(MolChemicalFeatureDef::CollectionType::const_iterator featDefIt=beginFeatureDefs(); featDefIt!=endFeatureDefs();featDefIt++){ MolChemicalFeatureDef::CollectionType::value_type featDef=*featDefIt; if(limits=="" || limits==featDef->getFamily()){ std::vector< MatchVectType > matches; #ifdef USE_VFLIB unsigned int numMatches=SubstructMatch(molG,*featDef->getPattern(),matches); #else unsigned int numMatches=SubstructMatch(mol,*featDef->getPattern(),matches); #endif for(unsigned int i=0;i<numMatches;i++){ const MatchVectType &match=matches[i]; std::set<int> matchSet; for(MatchVectType::const_iterator mIt=match.begin(); mIt!=match.end(); ++mIt){ matchSet.insert(mIt->second); } // loop over the matches we've already found and see if this one // is unique: bool unique=true; for(MatchSetCollection::const_iterator vsiCI=matchSets.begin(); vsiCI!=matchSets.end(); ++vsiCI){ if(vsiCI->first==featDef->getFamily() && std::includes(vsiCI->second.begin(),vsiCI->second.end(), matchSet.begin(),matchSet.end())){ unique=false; break; } } if(unique){ matchSets.push_back(std::make_pair(featDef->getFamily(),matchSet)); // Set up the feature: MolChemicalFeature *newFeat=new MolChemicalFeature(&mol,this,featDef.get(),idx++); MolChemicalFeature::AtomPtrContainer &atoms=newFeat->d_atoms; atoms.resize(match.size()); // set up the atoms: for(MatchVectType::const_iterator matchIt=match.begin(); matchIt!=match.end();matchIt++){ int atomIdx=matchIt->second; int queryIdx=matchIt->first; atoms[queryIdx]=mol.getAtomWithIdx(atomIdx); } // finally, add this to our result: res.push_back(FeatSPtrList::value_type(newFeat)); } } } } #ifdef USE_VFLIB #ifndef CACHE_ARMOLGRAPHS delete molG; #endif #endif return res; }