Package rdkit :: Package Chem :: Package FeatMaps :: Module FeatMapParser
[hide private]
[frames] | no frames]

Source Code for Module rdkit.Chem.FeatMaps.FeatMapParser

  1  # $Id$ 
  2  # 
  3  # Copyright (C) 2006 Greg Landrum 
  4  # 
  5  #   @@ All Rights Reserved @@ 
  6  #  This file is part of the RDKit. 
  7  #  The contents are covered by the terms of the BSD license 
  8  #  which is included in the file license.txt, found at the root 
  9  #  of the RDKit source tree. 
 10  # 
 11  from rdkit import Geometry 
 12  from rdkit.Chem import ChemicalFeatures 
 13  from rdkit.Chem.FeatMaps import FeatMaps,FeatMapPoint 
 14  import re 
 15   
 16  """ 
 17   
 18  ScoreMode=All 
 19  DirScoreMode=Ignore 
 20   
 21  BeginParams 
 22    family=Aromatic radius=2.5 width=1.0 profile=Gaussian 
 23    family=Acceptor radius=1.5 
 24  EndParams 
 25   
 26  # optional 
 27  BeginPoints 
 28    family=Acceptor pos=(1.0, 0.0, 5.0) weight=1.25 dir=(1, 1, 0) 
 29    family=Aromatic pos=(0.0,1.0,0.0) weight=2.0 dir=(0,0,1) dir=(0,0,-1) 
 30    family=Acceptor pos=(1.0,1.0,2.0) weight=1.25 
 31  EndPoints 
 32   
 33  """ 
 34   
35 -class FeatMapParseError(ValueError):
36 pass
37
38 -class FeatMapParser(object):
39 data=None
40 - def __init__(self,file=None,data=None):
41 if file: 42 self.data=file.readlines() 43 elif data: 44 self.SetData(data) 45 self._lineNum=0
46
47 - def SetData(self,data):
48 if isinstance(data,str): 49 self.data=data.split('\n') 50 else: 51 self.data=data 52 self._lineNum=0
53
54 - def _NextLine(self):
55 txt = '' 56 while 1: 57 try: 58 l = self.data[self._lineNum].split('#')[0].strip() 59 except IndexError: 60 break 61 self._lineNum+=1 62 if l: 63 txt += l 64 if l[-1]!='\\': 65 break 66 return txt
67
68 - def Parse(self,featMap=None):
69 if featMap is None: 70 featMap = FeatMaps.FeatMap() 71 72 l = self._NextLine().strip() 73 while l: 74 splitL = l.split('=') 75 if len(splitL)==1: 76 keyword=splitL[0].strip().lower() 77 if keyword=='beginpoints': 78 pts=self.ParseFeatPointBlock() 79 for pt in pts: 80 featMap.AddFeatPoint(pt) 81 elif keyword=='beginparams': 82 featMap.params=self.ParseParamBlock() 83 else: 84 raise FeatMapParseError('Unrecognized keyword %s on line %d'%(keyword,self._lineNum)) 85 else: 86 keyword = splitL[0].strip().lower() 87 val = splitL[1].strip() 88 if keyword=='scoremode': 89 try: 90 featMap.scoreMode=getattr(FeatMaps.FeatMapScoreMode,val) 91 except AttributeError: 92 raise FeatMapParseError('ScoreMode %s not recognized on line %d'%(val,self._lineNum)) 93 elif keyword=='dirscoremode': 94 try: 95 featMap.dirScoreMode=getattr(FeatMaps.FeatDirScoreMode,val) 96 except AttributeError: 97 raise FeatMapParseError('DirScoreMode %s not recognized on line %d'%(val,self._lineNum)) 98 else: 99 raise FeatMapParseError('Unrecognized keyword %s on line %d'%(keyword,self._lineNum)) 100 l = self._NextLine().strip() 101 return featMap
102
103 - def ParseParamBlock(self):
104 paramLineSplitter = re.compile(r'([a-zA-Z]+) *= *(\S+)') 105 params = {} 106 107 l = self._NextLine() 108 while l and l!='EndParams': 109 param = FeatMaps.FeatMapParams() 110 vals=paramLineSplitter.findall(l) 111 for name,val in vals: 112 name = name.lower() 113 if name=='family': 114 family=val 115 elif name=='radius': 116 param.radius=float(val) 117 elif name=='width': 118 param.width=float(val) 119 elif name=='profile': 120 try: 121 param.featProfile=getattr(param.FeatProfile,val) 122 except AttributeError: 123 raise FeatMapParseError('Profile %s not recognized on line %d'%(val,self._lineNum)) 124 else: 125 raise FeatMapParseError('FeatMapParam option %s not recognized on line %d'%(name,self._lineNum)) 126 params[family]=param 127 l = self._NextLine() 128 129 if l!='EndParams': 130 raise FeatMapParseError('EndParams line not found') 131 132 return params
133
134 - def _parsePoint(self,txt):
135 txt = txt.strip() 136 startP=0 137 endP=len(txt) 138 if txt[0]=='(': 139 startP += 1 140 if txt[-1]==')': 141 endP -= 1 142 txt = txt[startP:endP] 143 splitL = txt.split(',') 144 if len(splitL) != 3: 145 raise ValueError('Bad location string') 146 vs = [float(x) for x in splitL] 147 pt = Geometry.Point3D(vs[0],vs[1],vs[2]) 148 return pt
149 150
151 - def ParseFeatPointBlock(self):
152 featLineSplitter = re.compile(r'([a-zA-Z]+) *= *') 153 feats = [] 154 155 l = self._NextLine() 156 while l and l!='EndPoints': 157 vals=featLineSplitter.split(l) 158 while vals.count(''): vals.remove('') 159 p = FeatMapPoint.FeatMapPoint() 160 161 i=0 162 while i<len(vals): 163 name = vals[i].lower() 164 if name=='family': 165 i+=1 166 val = vals[i].strip() 167 p.SetFamily(val) 168 elif name=='weight': 169 i+=1 170 val = float(vals[i]) 171 p.weight = val 172 elif name=='pos': 173 i+=1 174 val = vals[i] 175 pos = self._parsePoint(val) 176 p.SetPos(pos) 177 elif name=='dir': 178 i+=1 179 val = vals[i] 180 pos = self._parsePoint(val) 181 p.featDirs.append(pos) 182 else: 183 raise FeatMapParseError('FeatPoint option %s not recognized on line %d'%(name,self._lineNum)) 184 i+=1 185 feats.append(p) 186 l = self._NextLine() 187 return feats
188 #------------------------------------ 189 # 190 # doctest boilerplate 191 #
192 -def _test():
193 import doctest,sys 194 return doctest.testmod(sys.modules["__main__"])
195 196 if __name__ == '__main__': 197 import sys 198 failed,tried = _test() 199 sys.exit(failed) 200