Package Chem :: Module SATIS
[hide private]
[frames] | no frames]

Source Code for Module Chem.SATIS

  1  # $Id: SATIS.py 2 2006-05-06 22:54:39Z glandrum $ 
  2  # 
  3  # Copyright (C) 2001-2006 greg Landrum and Rational Discovery LLC 
  4  # 
  5  #   @@ All Rights Reserved  @@ 
  6  # 
  7  """  Functionality for SATIS typing atoms 
  8   
  9  """ 
 10  import Chem 
 11   
 12  _debug = 0 
 13   
 14  # 
 15  #  These are SMARTS patterns for the special cases used in 
 16  #  SATIS typing. 
 17  # 
 18  aldehydePatt = Chem.MolFromSmarts('[CD2]=[OD1]') 
 19  ketonePatt = Chem.MolFromSmarts('[CD3]=[OD1]') 
 20  amidePatt = Chem.MolFromSmarts('[CD3](=[OD1])-[#7]') 
 21  esterPatt = Chem.MolFromSmarts('C(=[OD1])-O-[#6]') 
 22  carboxylatePatt = Chem.MolFromSmarts('C(=[OD1])-[OX1]') 
 23  carboxylPatt = Chem.MolFromSmarts('C(=[OD1])-[OX2]') 
 24   
 25  specialCases = ((carboxylatePatt,97), 
 26                  (esterPatt,96), 
 27                  (carboxylPatt,98), 
 28                  (amidePatt,95), 
 29                  (ketonePatt,94), 
 30                  (aldehydePatt,93)) 
 31   
 32   
33 -def SATISTypes(mol,neighborsToInclude=4):
34 """ returns SATIS codes for all atoms in a molecule 35 36 The SATIS definition used is from: 37 J. Chem. Inf. Comput. Sci. _39_ 751-757 (1999) 38 39 each SATIS code is a string consisting of _neighborsToInclude_ + 1 40 2 digit numbers 41 42 **Arguments** 43 44 - mol: a molecule 45 46 - neighborsToInclude (optional): the number of neighbors to include 47 in the SATIS codes 48 49 **Returns** 50 51 a list of strings nAtoms long 52 53 """ 54 global specialCases 55 56 nAtoms = mol.GetNumAtoms() 57 atomicNums = [0]*nAtoms 58 atoms = mol.GetAtoms() 59 for i in xrange(nAtoms): 60 atomicNums[i] = atoms[i].GetAtomicNum() 61 62 nSpecialCases = len(specialCases) 63 specialCaseMatches = [None]*nSpecialCases 64 for i,(patt,idx) in enumerate(specialCases): 65 if mol.HasSubstructMatch(patt): 66 specialCaseMatches[i] = mol.GetSubstructMatches(patt) 67 else: 68 specialCaseMatches[i] = () 69 70 codes = [None]*nAtoms 71 for i in range(nAtoms): 72 code = [99]*(neighborsToInclude+1) 73 atom = atoms[i] 74 atomIdx = atom.GetIdx() 75 code[0] = min(atom.GetAtomicNum(),99) 76 bonds = atom.GetBonds() 77 nBonds = len(bonds) 78 otherIndices = [-1]*nBonds 79 if _debug: print code[0], 80 for j in range(nBonds): 81 otherIndices[j] = bonds[j].GetOtherAtom(atom).GetIdx() 82 if _debug: print otherIndices[j], 83 if _debug: print 84 otherNums = [atomicNums[x] for x in otherIndices] + \ 85 [1]*atom.GetTotalNumHs() 86 otherNums.sort() 87 88 nOthers = len(otherNums) 89 if nOthers > neighborsToInclude: 90 otherNums.reverse() 91 otherNums = otherNums[:neighborsToInclude] 92 otherNums.reverse() 93 for j in range(neighborsToInclude): 94 code[j+1] = min(otherNums[j],99) 95 else: 96 for j in range(nOthers): 97 code[j+1] = min(otherNums[j],99) 98 if nOthers < neighborsToInclude and code[0] in [6,8]: 99 found = 0 100 for j in range(nSpecialCases): 101 for matchTuple in specialCaseMatches[j]: 102 if atomIdx in matchTuple: 103 code[-1] = specialCases[j][1] 104 found = 1 105 break 106 if found: 107 break 108 109 codes[i] = ''.join(['%02d'%(x) for x in code]) 110 return codes
111 112 if __name__ == '__main__': 113 smis = ['CC(=O)NC','CP(F)(Cl)(Br)(O)', 114 'O=CC(=O)C','C(=O)OCC(=O)O','C(=O)[O-]'] 115 for smi in smis: 116 print smi 117 m = Chem.MolFromSmiles(smi) 118 codes = SATISTypes(m) 119 print codes 120