Subgraphs::DiscrimTuple FragCatalogEntry::getDiscrims() const { Subgraphs::DiscrimTuple res; if (this->hasProp(common_properties::Discrims)) { this->getProp(common_properties::Discrims, res); } else { PATH_TYPE path; for (unsigned int i = 0; i < dp_mol->getNumBonds(); ++i) path.push_back(i); // create invariant additions to reflect the functional groups attached to // the atoms std::vector<std::uint32_t> funcGpInvars; gboost::hash<INT_VECT> vectHasher; for (ROMol::AtomIterator atomIt = dp_mol->beginAtoms(); atomIt != dp_mol->endAtoms(); ++atomIt) { unsigned int aid = (*atomIt)->getIdx(); std::uint32_t invar = 0; auto mapPos = d_aToFmap.find(aid); if (mapPos != d_aToFmap.end()) { INT_VECT fGroups = mapPos->second; std::sort(fGroups.begin(), fGroups.end()); invar = vectHasher(fGroups); } funcGpInvars.push_back(invar); } res = Subgraphs::calcPathDiscriminators(*dp_mol, path, true, &funcGpInvars); this->setProp(common_properties::Discrims, res); } // std::cout << "DISCRIMS: " << d_descrip << " "; // std::cout << res.get<0>() << " " << res.get<1>() << " " << res.get<2>(); // std::cout << std::endl; return res; }
FragCatalogEntry::FragCatalogEntry(const ROMol *omol, const PATH_TYPE &path, const MatchVectType &aidToFid) { PRECONDITION(omol, "bad mol"); // start with the assumption that this entry is not participating in // any find of fingerprinting d_aToFmap.clear(); setBitId(-1); INT_MAP_INT aIdxMap; // a map from atom id in omol to the new atoms id in mol dp_mol = Subgraphs::pathToSubmol(*omol, path, false, aIdxMap); // Using Subgraphs functionality d_order = path.size(); // using aIdxMap initialize the location (and their IDs) of the // functional groups on dp_mol for (const auto &mvtci : aidToFid) { int oldAid = mvtci.first; if (aIdxMap.find(oldAid) != aIdxMap.end()) { int newAid = aIdxMap[oldAid]; if (d_aToFmap.find(newAid) != d_aToFmap.end()) { d_aToFmap[newAid].push_back(mvtci.second); } else { INT_VECT tmpVect; tmpVect.clear(); tmpVect.push_back(mvtci.second); d_aToFmap[newAid] = tmpVect; } } } dp_props = new Dict(); d_descrip = ""; }
std::vector<unsigned int> generateBondHashes(const ROMol &mol, boost::dynamic_bitset<>& atomsInPath, const std::vector<const Bond *>& bondCache, const std::vector<short>& isQueryBond, const PATH_TYPE &path, bool useBondOrder, std::vector<boost::uint32_t> *atomInvariants){ PRECONDITION(!atomInvariants || atomInvariants->size() >= mol.getNumAtoms(), "bad atomInvariants size"); std::vector<unsigned int> bondHashes; atomsInPath.reset(); bool queryInPath=false; std::vector<unsigned int> atomDegrees(mol.getNumAtoms(),0); for(unsigned int i=0;i<path.size() && !queryInPath;++i){ const Bond *bi = bondCache[path[i]]; atomDegrees[bi->getBeginAtomIdx()]++; atomDegrees[bi->getEndAtomIdx()]++; atomsInPath.set(bi->getBeginAtomIdx()); atomsInPath.set(bi->getEndAtomIdx()); if(isQueryBond[path[i]]) queryInPath=true; } if(queryInPath){ return bondHashes; } // ----------------- // calculate the bond hashes: std::vector<unsigned int> bondNbrs(path.size(),0); bondHashes.reserve(path.size()+1); for(unsigned int i=0;i<path.size();++i){ const Bond *bi = bondCache[path[i]]; #ifdef REPORT_FP_STATS if (std::find(atomsToUse.begin(), atomsToUse.end(), bi->getBeginAtomIdx()) == atomsToUse.end()) { atomsToUse.push_back(bi->getBeginAtomIdx()); } if (std::find(atomsToUse.begin(), atomsToUse.end(), bi->getEndAtomIdx()) == atomsToUse.end()) { atomsToUse.push_back(bi->getEndAtomIdx()); } #endif for(unsigned int j=i+1;j<path.size();++j){ const Bond *bj = bondCache[path[j]]; if(bi->getBeginAtomIdx()==bj->getBeginAtomIdx() || bi->getBeginAtomIdx()==bj->getEndAtomIdx() || bi->getEndAtomIdx()==bj->getBeginAtomIdx() || bi->getEndAtomIdx()==bj->getEndAtomIdx() ){ ++bondNbrs[i]; ++bondNbrs[j]; } } #ifdef VERBOSE_FINGERPRINTING std::cerr << " bond(" << i << "):" << bondNbrs[i] << std::endl; #endif // we have the count of neighbors for bond bi, compute its hash: unsigned int a1Hash = (*atomInvariants)[bi->getBeginAtomIdx()]; unsigned int a2Hash = (*atomInvariants)[bi->getEndAtomIdx()]; unsigned int deg1=atomDegrees[bi->getBeginAtomIdx()]; unsigned int deg2=atomDegrees[bi->getEndAtomIdx()]; if(a1Hash<a2Hash){ std::swap(a1Hash,a2Hash); std::swap(deg1,deg2); } else if(a1Hash==a2Hash && deg1<deg2){ std::swap(deg1,deg2); } unsigned int bondHash=1; if(useBondOrder){ if(bi->getIsAromatic() || bi->getBondType()==Bond::AROMATIC){ // makes sure aromatic bonds always hash as aromatic bondHash = Bond::AROMATIC; } else { bondHash = bi->getBondType(); } } boost::uint32_t ourHash=bondNbrs[i]; gboost::hash_combine(ourHash,bondHash); gboost::hash_combine(ourHash,a1Hash); gboost::hash_combine(ourHash,deg1); gboost::hash_combine(ourHash,a2Hash); gboost::hash_combine(ourHash,deg2); bondHashes.push_back(ourHash); //std::cerr<<" "<<bi->getIdx()<<" "<<a1Hash<<"("<<deg1<<")"<<"-"<<a2Hash<<"("<<deg2<<")"<<" "<<bondHash<<" -> "<<ourHash<<std::endl; } return bondHashes; }