def testAtomMatch(self): fdefBlock = \ """ DefineFeature HAcceptor1 [#7,#8] Family HBondAcceptor Weights 1.0 EndFeature DefineFeature Arom1 a1aaaaa1 Family Aromatic Weights 1.0,1.0,1.0,1.0,1.0,1.0 EndFeature """ cfac = ChemicalFeatures.BuildFeatureFactoryFromString(fdefBlock) self.failUnless(cfac.GetNumFeatureDefs() == 2) mol = Chem.MolFromSmiles('n1ccccc1') feats = cfac.GetFeaturesForMol(mol) self.failUnless(len(feats)==2) m = ChemicalFeatures.GetAtomMatch(feats) self.failIf(m) mol = Chem.MolFromSmiles('c1ccccc1N') feats = cfac.GetFeaturesForMol(mol) self.failUnless(len(feats)==2) m = ChemicalFeatures.GetAtomMatch(feats) self.failUnless(len(m)==2)
def ConstrainedEnum(matches,mol,pcophore,bounds,use2DLimits=False, index=0,soFar=[]): """ Enumerates the list of atom mappings a molecule has to a particular pharmacophore. We do check distance bounds here. """ nMatches = len(matches) if index>=nMatches: yield soFar,[] elif index==nMatches-1: for entry in matches[index]: nextStep = soFar+[entry] if index != 0: atomMatch = _checkMatch(nextStep,mol,bounds,pcophore,use2DLimits) else: atomMatch = ChemicalFeatures.GetAtomMatch(nextStep) if atomMatch: yield soFar+[entry],atomMatch else: for entry in matches[index]: nextStep = soFar+[entry] if index != 0: atomMatch = _checkMatch(nextStep,mol,bounds,pcophore,use2DLimits) if not atomMatch: continue for val in ConstrainedEnum(matches,mol,pcophore,bounds,use2DLimits=use2DLimits, index=index+1,soFar=nextStep): if val: yield val
def GetAllPharmacophoreMatches(matches, bounds, pcophore, useDownsampling=0, progressCallback=None, use2DLimits=False, mol=None, verbose=False): res = [] nDone = 0 for match in CombiEnum(matches): atomMatch = ChemicalFeatures.GetAtomMatch(match) if atomMatch and use2DLimits and mol: pass2D = Check2DBounds(atomMatch, mol, pcophore) if verbose: print('..', atomMatch) print(' ..Pass2d:', pass2D) else: pass2D = True if atomMatch and pass2D and \ CoarseScreenPharmacophore(atomMatch,bounds,pcophore,verbose=verbose): if verbose: print(' ..CoarseScreen: Pass') bm = bounds.copy() if verbose: print('pre update:') for row in bm: print(' ', ' '.join(['% 4.2f' % x for x in row])) bm = UpdatePharmacophoreBounds(bm, atomMatch, pcophore) sz = bm.shape[0] if verbose: print('pre downsample:') for row in bm: print(' ', ' '.join(['% 4.2f' % x for x in row])) if useDownsampling: indices = [] for entry in atomMatch: indices += list(entry) bm = DownsampleBoundsMatrix(bm, indices) if verbose: print('post downsample:') for row in bm: print(' ', ' '.join(['% 4.2f' % x for x in row])) if DG.DoTriangleSmoothing(bm): res.append(match) elif verbose: print('cannot smooth') nDone += 1 if progressCallback: progressCallback(nDone) return res
def _checkMatch(match, mol, bounds, pcophore, use2DLimits): """ **INTERNAL USE ONLY** checks whether a particular atom match can be satisfied by a molecule """ atomMatch = ChemicalFeatures.GetAtomMatch(match) if not atomMatch: return None elif use2DLimits: if not Check2DBounds(atomMatch, mol, pcophore): return None if not CoarseScreenPharmacophore(atomMatch, bounds, pcophore): return None return atomMatch