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 lib.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