1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 15   
 16   
 17   
 18   
 19   
 20   
 21   
 22   
 23  """Module containing functions for the parsing and creation of Xplor formatted files.""" 
 24   
 25   
 26  from re import search 
 27   
 28   
 29  from relax_errors import RelaxError 
 30   
 31   
 33      """Convert the string into a relax atom id representation. 
 34   
 35      @param string:  The Xplor atom string. 
 36      @type string:   str 
 37      @return:        The relax atom id. 
 38      @rtype:         str 
 39      """ 
 40   
 41       
 42      data = string.split('and') 
 43   
 44       
 45      relax_id = '' 
 46      for i in range(len(data)): 
 47           
 48          info = data[i].split() 
 49   
 50           
 51          if len(info) != 2: 
 52              raise RelaxError("Cannot convert the Xplor atom string '%s' to relax format." % string) 
 53   
 54           
 55          if info[0] == 'segid': 
 56              relax_id = relax_id + '#' + info[1] 
 57   
 58           
 59          elif info[0] == 'resid': 
 60              relax_id = relax_id + ':' + info[1] 
 61   
 62           
 63          elif info[0] == 'name': 
 64              relax_id = relax_id + '@' + info[1] 
 65   
 66       
 67      return relax_id 
  68   
 69   
 71      """Parse and return the NOE restraints from the Xplor lines. 
 72   
 73      @param lines:   The Xplor formatted file, or file fragment, split into lines. 
 74      @type lines:    list of str 
 75      @return:        The NOE restraint list in the format of two atom identification strings (or list 
 76                      of str for pseudoatoms) and the lower and upper restraints. 
 77      @rtype:         list of lists of str, str, float, float 
 78      """ 
 79   
 80       
 81      lines = strip_comments(lines) 
 82   
 83       
 84      data = [] 
 85   
 86       
 87      for id1, id2, noe, lower, upper in first_parse(lines): 
 88           
 89          id1 = second_parse(id1) 
 90          id2 = second_parse(id2) 
 91   
 92           
 93          if isinstance(id1, list): 
 94              relax_id1 = [] 
 95              for i in range(len(id1)): 
 96                  relax_id1.append(__convert_to_id(id1[i])) 
 97          else: 
 98              relax_id1 = __convert_to_id(id1) 
 99   
100          if isinstance(id2, list): 
101              relax_id2 = [] 
102              for i in range(len(id2)): 
103                  relax_id2.append(__convert_to_id(id2[i])) 
104          else: 
105              relax_id2 = __convert_to_id(id2) 
106   
107           
108          lower_bound = noe - lower 
109          upper_bound = noe + upper 
110   
111           
112          data.append([relax_id1, relax_id2, lower_bound, upper_bound]) 
113   
114       
115      return data 
 116   
117   
119      """Generator function to parse and extract the 2 atom IDs and NOE info from the lines. 
120   
121      The first parse loops over and returns the data from assign statements, returning pseudo atoms 
122      as single strings.  The second parse splits the pseudoatoms. 
123   
124      @param lines:   The Xplor formatted file, or file fragment, split into lines. 
125      @type lines:    list of str 
126      @return:        The 2 atom IDs, and NOE info (NOE, upper, and lower bounds). 
127      @rtype:         str, str, float, float, float 
128      """ 
129   
130       
131      line_index = 0 
132      while True: 
133           
134          if line_index >= len(lines): 
135              break 
136   
137           
138          if search('^assign', lines[line_index]): 
139               
140              char_index = -1 
141   
142               
143              id = ['', ''] 
144              id_index = 0 
145              inside = 0 
146              while True: 
147                   
148                  char_index = char_index + 1 
149   
150                   
151                  if line_index >= len(lines): 
152                      break 
153   
154                   
155                  if char_index >= len(lines[line_index]): 
156                      line_index = line_index + 1 
157                      char_index = -1 
158                      continue 
159   
160                   
161                  if lines[line_index][char_index] == '(': 
162                      inside = inside + 1 
163   
164                       
165                      if inside == 1: 
166                          continue 
167   
168                   
169                  if not inside: 
170                      continue 
171   
172                   
173                  elif lines[line_index][char_index] == ')': 
174                      inside = inside - 1 
175   
176                   
177                  if inside < 0: 
178                      raise RelaxError("Improperly formatted Xplor file, unmatched ')'.") 
179   
180                   
181                  if inside: 
182                      id[id_index] = id[id_index] + lines[line_index][char_index] 
183   
184                   
185                  if inside == 0: 
186                      if id_index == 1: 
187                          break 
188                      else: 
189                          id_index = 1 
190   
191               
192              info = lines[line_index][char_index+1:].split() 
193   
194               
195              noe = float(info[0]) 
196              lower = float(info[1]) 
197              upper = float(info[2]) 
198   
199           
200          else: 
201               
202              line_index = line_index + 1 
203   
204               
205              continue 
206   
207           
208          line_index = line_index + 1 
209   
210           
211          yield id[0], id[1], noe, lower, upper 
 212   
213   
215      """Split up pseudoatoms. 
216   
217      @param id:  The Xplor atom id without outer brackets, i.e. a single atom or a list of atoms in 
218                  the case of pseudoatoms. 
219      @type id:   str 
220      @return:    For normal atoms, the id string is returned unmodified.  For pseudoatoms, a list of 
221                  strings, with brackets removed, is returned. 
222      @rtype:     str or list of str 
223      """ 
224   
225       
226      atoms = [''] 
227      index = -1 
228      inside = False 
229      while True: 
230           
231          index = index + 1 
232   
233           
234          if index >= len(id): 
235              break 
236   
237           
238          if id[index] == '(': 
239               
240              if inside: 
241                  raise RelaxError("The Xplor pseudoatom ID string '%s' is invalid." % id) 
242   
243               
244              inside = True 
245   
246               
247              continue 
248   
249           
250          if not inside: 
251              continue 
252   
253           
254          if id[index] == ')': 
255              inside = False 
256   
257           
258          if inside: 
259              atoms[-1] = atoms[-1] + id[index] 
260   
261           
262          if not inside: 
263              atoms.append('') 
264   
265       
266      if atoms[0] and atoms[-1] == '': 
267          atoms = atoms[:-1] 
268   
269       
270      if not atoms[0]: 
271          return id 
272      else: 
273          return atoms 
 274   
275   
307