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