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 for handling the molecule, residue, and spin sequence."""
25
26
27 from types import IntType, NoneType
28
29
30 from generic_fns.mol_res_spin import count_molecules, count_residues, count_spins, exists_mol_res_spin_data, generate_spin_id, return_molecule, return_residue, return_spin, spin_id_to_data_list, spin_loop
31 import pipes
32 from relax_errors import RelaxError, RelaxDiffMolNumError, RelaxDiffResNumError, RelaxDiffSeqError, RelaxDiffSpinNumError, RelaxFileEmptyError, RelaxInvalidSeqError, RelaxNoSequenceError, RelaxSequenceError
33 from relax_io import open_write_file, read_spin_data, write_spin_data
34 import sys
35
36
37
38 -def copy(pipe_from=None, pipe_to=None, preserve_select=False, verbose=True):
39 """Copy the molecule, residue, and spin sequence data from one data pipe to another.
40
41 @keyword pipe_from: The data pipe to copy the sequence data from. This defaults to the
42 current data pipe.
43 @type pipe_from: str
44 @keyword pipe_to: The data pipe to copy the sequence data to. This defaults to the
45 current data pipe.
46 @type pipe_to: str
47 @keyword preserve_select: A flag which if True will cause spin selections to be preserved.
48 @type preserve_select: bool
49 @keyword verbose: A flag which if True will cause info about each spin to be printed
50 out as the sequence is generated.
51 @type verbose: bool
52 """
53
54
55 if pipe_from == None and pipe_to == None:
56 raise RelaxError("The pipe_from and pipe_to arguments cannot both be set to None.")
57 elif pipe_from == None:
58 pipe_from = pipes.cdp_name()
59 elif pipe_to == None:
60 pipe_to = pipes.cdp_name()
61
62
63 pipes.test(pipe_from)
64 pipes.test(pipe_to)
65
66
67 if not exists_mol_res_spin_data(pipe_from):
68 raise RelaxNoSequenceError
69
70
71 if exists_mol_res_spin_data(pipe_to):
72 raise RelaxSequenceError
73
74
75 for spin, mol_name, res_num, res_name in spin_loop(pipe=pipe_from, full_info=True):
76
77 if preserve_select:
78 select = spin.select
79 else:
80 select = True
81
82
83 generate(mol_name, res_num, res_name, spin.num, spin.name, pipe_to, select=select, verbose=verbose)
84
85
87 """Compare the sequence in two data pipes.
88
89 @keyword pipe1: The name of the first data pipe.
90 @type pipe1: str
91 @keyword pipe2: The name of the second data pipe.
92 @type pipe2: str
93 @keyword fail: A flag which if True causes a RelaxError to be raised.
94 @type fail: bool
95 @return: 1 if the sequence is the same, 0 if different.
96 @rtype: int
97 @raises RelaxError: If the sequence is different and the fail flag is True.
98 """
99
100
101 status = 1
102
103
104 if count_molecules(pipe=pipe1) != count_molecules(pipe=pipe2):
105 status = 0
106 if fail:
107 raise RelaxDiffMolNumError(pipe1, pipe2)
108
109
110 if count_residues(pipe=pipe1) != count_residues(pipe=pipe2):
111 status = 0
112 if fail:
113 raise RelaxDiffResNumError(pipe1, pipe2)
114
115
116 if count_spins(pipe=pipe1) != count_spins(pipe=pipe2):
117 status = 0
118 if fail:
119 raise RelaxDiffSpinNumError(pipe1, pipe2)
120
121
122 seq1 = ''
123 seq2 = ''
124 for spin, spin_id in spin_loop(return_id=True, pipe=pipe1):
125 seq1 = seq1 + spin_id + '\n'
126 for spin, spin_id in spin_loop(return_id=True, pipe=pipe2):
127 seq2 = seq2 + spin_id + '\n'
128
129
130 if seq1 != seq2:
131 status = 0
132 if fail:
133 raise RelaxDiffSeqError(pipe1, pipe2)
134
135
136 return status
137
138
139 -def display(sep=None, mol_name_flag=False, res_num_flag=False, res_name_flag=False, spin_num_flag=False, spin_name_flag=False):
140 """Display the molecule, residue, and/or spin sequence data.
141
142 This calls the write() function to do most of the work.
143
144
145 @keyword sep: The column seperator which, if None, defaults to whitespace.
146 @type sep: str or None
147 @keyword mol_name_flag: A flag which if True will cause the molecule name column to be
148 written.
149 @type mol_name_flag: bool
150 @keyword res_num_flag: A flag which if True will cause the residue number column to be
151 written.
152 @type res_num_flag: bool
153 @keyword res_name_flag: A flag which if True will cause the residue name column to be
154 written.
155 @type res_name_flag: bool
156 @keyword spin_name_flag: A flag which if True will cause the spin name column to be written.
157 @type spin_name_flag: bool
158 @keyword spin_num_flag: A flag which if True will cause the spin number column to be
159 written.
160 @type spin_num_flag: bool
161 @param mol_name_flag: The column to contain the molecule name information.
162 """
163
164
165 if not count_spins():
166 raise RelaxNoSequenceError
167
168
169 write(file=sys.stdout, sep=sep, mol_name_flag=mol_name_flag, res_num_flag=res_num_flag, res_name_flag=res_name_flag, spin_num_flag=spin_num_flag, spin_name_flag=spin_name_flag)
170
171
172 -def generate(mol_name=None, res_num=None, res_name=None, spin_num=None, spin_name=None, pipe=None, select=True, verbose=True):
173 """Generate the sequence item-by-item by adding a single molecule/residue/spin container as necessary.
174
175 @keyword mol_name: The molecule name.
176 @type mol_name: str or None
177 @keyword res_num: The residue number.
178 @type res_num: int or None
179 @keyword res_name: The residue name.
180 @type res_name: str or None
181 @keyword spin_num: The spin number.
182 @type spin_num: int or None
183 @keyword spin_name: The spin name.
184 @type spin_name: str or None
185 @keyword pipe: The data pipe in which to generate the sequence. This defaults to the current data pipe.
186 @type pipe: str
187 @keyword select: The spin selection flag.
188 @type select: bool
189 @keyword verbose: A flag which if True will cause info about each spin to be printed out as the sequence is generated.
190 @type verbose: bool
191 @return: True if a new spin was created, False otherwise.
192 @rtype: bool
193 """
194
195
196 if pipe == None:
197 pipe = pipes.cdp_name()
198
199
200 dp = pipes.get_pipe(pipe)
201
202
203 curr_mol = return_molecule(generate_spin_id(mol_name=mol_name), pipe=pipe)
204
205
206 if not curr_mol:
207
208 dp.mol.add_item(mol_name=mol_name)
209 curr_mol = dp.mol[-1]
210
211
212 curr_res = return_residue(generate_spin_id(mol_name=mol_name, res_num=res_num, res_name=res_name), pipe=pipe)
213
214
215 if not curr_res:
216
217 curr_mol.res.add_item(res_name=res_name, res_num=res_num)
218 curr_res = curr_mol.res[-1]
219
220
221 curr_spin = return_spin(generate_spin_id(mol_name=mol_name, res_num=res_num, res_name=res_name, spin_num=spin_num, spin_name=spin_name), pipe=pipe)
222
223
224 new_data = False
225 if not curr_spin:
226
227 curr_res.spin.add_item(spin_name=spin_name, spin_num=spin_num)
228
229
230 curr_spin = return_spin(generate_spin_id(mol_name=mol_name, res_num=res_num, res_name=res_name, spin_num=spin_num, spin_name=spin_name), pipe=pipe)
231
232
233 new_data = True
234
235
236 curr_spin.select = select
237
238
239 return new_data
240
241
242 -def read(file=None, dir=None, file_data=None, spin_id_col=None, mol_name_col=None, res_num_col=None, res_name_col=None, spin_num_col=None, spin_name_col=None, sep=None, spin_id=None):
243 """Read the molecule, residue, and/or spin sequence data from file.
244
245 @param file: The name of the file to open.
246 @type file: str
247 @param dir: The directory containing the file (defaults to the current directory if
248 None).
249 @type dir: str or None
250 @keyword file_data: An alternative to opening a file, if the data already exists in the
251 correct format. The format is a list of lists where the first index
252 corresponds to the row and the second the column.
253 @type file_data: list of lists
254 @keyword spin_id_col: The column containing the spin ID strings. If supplied, the
255 mol_name_col, res_name_col, res_num_col, spin_name_col, and spin_num_col
256 arguments must be none.
257 @type spin_id_col: int or None
258 @keyword mol_name_col: The column containing the molecule name information. If supplied,
259 spin_id_col must be None.
260 @type mol_name_col: int or None
261 @keyword res_name_col: The column containing the residue name information. If supplied,
262 spin_id_col must be None.
263 @type res_name_col: int or None
264 @keyword res_num_col: The column containing the residue number information. If supplied,
265 spin_id_col must be None.
266 @type res_num_col: int or None
267 @keyword spin_name_col: The column containing the spin name information. If supplied,
268 spin_id_col must be None.
269 @type spin_name_col: int or None
270 @keyword spin_num_col: The column containing the spin number information. If supplied,
271 spin_id_col must be None.
272 @type spin_num_col: int or None
273 @keyword sep: The column separator which, if None, defaults to whitespace.
274 @type sep: str or None
275 @keyword spin_id: The spin ID string used to restrict data loading to a subset of all
276 spins.
277 @type spin_id: None or str
278 """
279
280
281 pipes.test()
282
283
284 if exists_mol_res_spin_data():
285 raise RelaxSequenceError
286
287
288 mol_names = []
289 res_nums = []
290 res_names = []
291 spin_nums = []
292 spin_names = []
293
294
295 for mol_name, res_num, res_name, spin_num, spin_name in read_spin_data(file=file, dir=dir, file_data=file_data, spin_id_col=spin_id_col, mol_name_col=mol_name_col, res_num_col=res_num_col, res_name_col=res_name_col, spin_num_col=spin_num_col, spin_name_col=spin_name_col, sep=sep, spin_id=spin_id):
296
297 new_spin = generate(mol_name=mol_name, res_num=res_num, res_name=res_name, spin_num=spin_num, spin_name=spin_name)
298
299
300 if new_spin:
301 mol_names.append(mol_name)
302 res_nums.append(res_num)
303 res_names.append(res_name)
304 spin_nums.append(spin_num)
305 spin_names.append(spin_name)
306
307
308 write_spin_data(sys.stdout, mol_names=mol_names, res_nums=res_nums, res_names=res_names, spin_nums=spin_nums, spin_names=spin_names)
309
310
311 -def validate_sequence(data, spin_id_col=None, mol_name_col=None, res_num_col=None, res_name_col=None, spin_num_col=None, spin_name_col=None, data_col=None, error_col=None):
312 """Test if the sequence data is valid.
313
314 The only function this performs is to raise a RelaxError if the data is invalid.
315
316
317 @param data: The sequence data.
318 @type data: list of lists.
319 @keyword spin_id_col: The column containing the spin ID strings.
320 @type spin_id_col: int or None
321 @param mol_name_col: The column containing the molecule name information.
322 @type mol_name_col: int or None
323 @param res_name_col: The column containing the residue name information.
324 @type res_name_col: int or None
325 @param res_num_col: The column containing the residue number information.
326 @type res_num_col: int or None
327 @param spin_name_col: The column containing the spin name information.
328 @type spin_name_col: int or None
329 @param spin_num_col: The column containing the spin number information.
330 @type spin_num_col: int or None
331 """
332
333
334 if spin_id_col:
335 if len(data) < spin_id_col:
336 raise RelaxInvalidSeqError(data, "the Spin ID data is missing")
337
338
339 if mol_name_col:
340 if len(data) < mol_name_col:
341 raise RelaxInvalidSeqError(data, "the molecule name data is missing")
342
343
344 if res_num_col:
345
346 if len(data) < res_num_col:
347 raise RelaxInvalidSeqError(data, "the residue number data is missing")
348
349
350 try:
351 res_num = eval(data[res_num_col-1])
352 if not (isinstance(res_num, NoneType) or isinstance(res_num, IntType)):
353 raise ValueError
354 except:
355 raise RelaxInvalidSeqError(data, "the residue number data '%s' is invalid" % data[res_num_col-1])
356
357
358 if res_name_col:
359 if len(data) < res_name_col:
360 raise RelaxInvalidSeqError(data, "the residue name data is missing")
361
362
363 if spin_num_col:
364
365 if len(data) < spin_num_col:
366 raise RelaxInvalidSeqError(data, "the spin number data is missing")
367
368
369 try:
370 res_num = eval(data[res_num_col-1])
371 if not (isinstance(res_num, NoneType) or isinstance(res_num, IntType)):
372 raise ValueError
373 except:
374 raise RelaxInvalidSeqError(data, "the spin number data '%s' is invalid" % data[res_num_col-1])
375
376
377 if spin_name_col:
378 if len(data) < spin_name_col:
379 raise RelaxInvalidSeqError(data, "the spin name data is missing")
380
381
382 if data_col:
383 if len(data) < data_col:
384 raise RelaxInvalidSeqError(data, "the data is missing")
385
386
387 if error_col:
388 if len(data) < error_col:
389 raise RelaxInvalidSeqError(data, "the error data is missing")
390
391
392 -def write(file, dir=None, sep=None, mol_name_flag=True, res_num_flag=True, res_name_flag=True, spin_num_flag=True, spin_name_flag=True, force=False):
393 """Write the molecule, residue, and/or sequence data.
394
395 This calls the relax_io.write_spin_data() function to do most of the work.
396
397
398 @param file: The name of the file to write the data to.
399 @type file: str
400 @keyword dir: The directory to contain the file (defaults to the current directory if None).
401 @type dir: str or None
402 @keyword sep: The column seperator which, if None, defaults to whitespace.
403 @type sep: str or None
404 @keyword mol_name_flag: A flag which if True will cause the molecule name column to be written.
405 @type mol_name_flag: bool
406 @keyword res_num_flag: A flag which if True will cause the residue number column to be written.
407 @type res_num_flag: bool
408 @keyword res_name_flag: A flag which if True will cause the residue name column to be written.
409 @type res_name_flag: bool
410 @keyword spin_name_flag: A flag which if True will cause the spin name column to be written.
411 @type spin_name_flag: bool
412 @keyword spin_num_flag: A flag which if True will cause the spin number column to be written.
413 @keyword force: A flag which if True will cause an existing file to be overwritten.
414 @type force: bin
415 """
416
417
418 if not count_spins():
419 raise RelaxNoSequenceError
420
421
422 mol_names = []
423 res_nums = []
424 res_names = []
425 spin_nums = []
426 spin_names = []
427
428
429 for spin, mol_name, res_num, res_name in spin_loop(full_info=True):
430 mol_names.append(mol_name)
431 res_nums.append(res_num)
432 res_names.append(res_name)
433 spin_nums.append(spin.num)
434 spin_names.append(spin.name)
435
436
437 if not mol_name_flag:
438 mol_names = None
439 if not res_num_flag:
440 res_nums = None
441 if not res_name_flag:
442 res_names = None
443 if not spin_num_flag:
444 spin_nums = None
445 if not spin_name_flag:
446 spin_names = None
447
448
449 write_spin_data(file=file, dir=dir, sep=sep, mol_names=mol_names, res_nums=res_nums, res_names=res_names, spin_nums=spin_nums, spin_names=spin_names, force=force)
450