def GetBitInfo(self, idx): """ returns information about the given bit **Arguments** - idx: the bit index to be considered **Returns** a 3-tuple: 1) the number of points in the pharmacophore 2) the proto-pharmacophore (tuple of pattern indices) 3) the scaffold (tuple of distance indices) """ if idx >= self._sigSize: raise IndexError('bad index (%d) queried. %d is the max' % (idx, self._sigSize)) # first figure out how many points are in the p'cophore nPts = self.minPointCount while nPts < self.maxPointCount and self._starts[nPts + 1] <= idx: nPts += 1 # how far are we in from the start point? offsetFromStart = idx - self._starts[nPts] if _verbose: print('\t %d Points, %d offset' % (nPts, offsetFromStart)) # lookup the number of scaffolds nDists = len(Utils.nPointDistDict[nPts]) scaffolds = self._scaffolds[nDists] nScaffolds = len(scaffolds) # figure out to which proto-pharmacophore we belong: protoIdx = offsetFromStart // nScaffolds indexCombos = Utils.GetIndexCombinations(self._nFeats, nPts) combo = tuple(indexCombos[protoIdx]) if _verbose: print('\t combo: %s' % (str(combo))) # and which scaffold: scaffoldIdx = offsetFromStart % nScaffolds scaffold = scaffolds[scaffoldIdx] if _verbose: print('\t scaffold: %s' % (str(scaffold))) return nPts, combo, scaffold
def Gen2DFingerprint(mol, sigFactory, perms=None, dMat=None): """ generates a 2D fingerprint for a molecule using the parameters in _sig_ **Arguments** - mol: the molecule for which the signature should be generated - sigFactory : the SigFactory object with signature parameters NOTE: no preprocessing is carried out for _sigFactory_. It *must* be pre-initialized. - perms: (optional) a sequence of permutation indices limiting which pharmacophore combinations are allowed - dMat: (optional) the distance matrix to be used """ if not isinstance(sigFactory, SigFactory.SigFactory): raise ValueError('bad factory') featFamilies = sigFactory.GetFeatFamilies() if _verbose: print('* feat famillies:', featFamilies) nFeats = len(featFamilies) minCount = sigFactory.minPointCount maxCount = sigFactory.maxPointCount if maxCount > 3: logger.warning( ' Pharmacophores with more than 3 points are not currently supported.\nSetting maxCount to 3.' ) maxCount = 3 # generate the molecule's distance matrix, if required if dMat is None: from rdkit import Chem useBO = sigFactory.includeBondOrder dMat = Chem.GetDistanceMatrix(mol, useBO) # generate the permutations, if required if perms is None: perms = [] for count in range(minCount, maxCount + 1): perms += Utils.GetIndexCombinations(nFeats, count) # generate the matches: featMatches = sigFactory.GetMolFeats(mol) if _verbose: print(' featMatches:', featMatches) sig = sigFactory.GetSignature() for perm in perms: # the permutation is a combination of feature indices # defining the feature set for a proto-pharmacophore featClasses = [0] for i in range(1, len(perm)): if perm[i] == perm[i - 1]: featClasses.append(featClasses[-1]) else: featClasses.append(featClasses[-1] + 1) # Get a set of matches at each index of # the proto-pharmacophore. matchPerms = [featMatches[x] for x in perm] if _verbose: print('\n->Perm: %s' % (str(perm))) print(' matchPerms: %s' % (str(matchPerms))) # Get all unique combinations of those possible matches: matchesToMap = Utils.GetUniqueCombinations(matchPerms, featClasses) for i, entry in enumerate(matchesToMap): entry = [x[1] for x in entry] matchesToMap[i] = entry if _verbose: print(' mtM:', matchesToMap) for match in matchesToMap: if sigFactory.shortestPathsOnly: _ShortestPathsMatch(match, perm, sig, dMat, sigFactory) return sig