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