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 the manipulation of parameter and constant values."""
25
26
27 from numpy import ndarray
28 import sys
29
30
31 from generic_fns import minimise, pipes
32 from generic_fns.mol_res_spin import exists_mol_res_spin_data, generate_spin_id, generate_spin_id_data_array, return_spin, spin_loop
33 from relax_errors import RelaxError, RelaxNoSequenceError, RelaxNoSpinError, RelaxParamSetError, RelaxValueError
34 from relax_io import get_file_path, open_write_file, read_spin_data, write_spin_data
35 import specific_fns
36 from status import Status; status = Status()
37
38
39 -def copy(pipe_from=None, pipe_to=None, param=None):
40 """Copy spin specific data values from pipe_from to pipe_to.
41
42 @param pipe_from: The data pipe to copy the value from. This defaults to the current data
43 pipe.
44 @type pipe_from: str
45 @param pipe_to: The data pipe to copy the value to. This defaults to the current data pipe.
46 @type pipe_to: str
47 @param param: The name of the parameter to copy the values of.
48 @type param: str
49 """
50
51
52 if pipe_from == None:
53 pipe_from = pipes.cdp_name()
54 if pipe_to == None:
55 pipe_to = pipes.cdp_name()
56
57
58 pipes.test(pipe_to)
59
60
61 if not exists_mol_res_spin_data(pipe_from):
62 raise RelaxNoSequenceError(pipe_from)
63
64
65 if not exists_mol_res_spin_data(pipe_to):
66 raise RelaxNoSequenceError(pipe_to)
67
68
69 return_value = specific_fns.setup.get_specific_fn('return_value', pipes.get_type(pipe_from))
70
71
72 for spin in spin_loop(pipe_to):
73
74 value, error = return_value(spin, param)
75
76
77 if value != None or error != None:
78 raise RelaxValueError(param, pipe_to)
79
80
81 for spin, spin_id in spin_loop(pipe_from, return_id=True):
82
83 value, error = return_value(spin, param)
84
85
86 spin_to = return_spin(spin_id, pipe_to)
87
88
89 set(spin_id=spin_to, value=value, error=error, param=param)
90
91
92 minimise.reset_min_stats(pipe_to)
93
94
111
112
147
148
150 """Function for sorting and partitioning the parameters and their values.
151
152 The two major partitions are the tensor parameters and the spin specific parameters.
153
154 @param val: The parameter values.
155 @type val: None, number, or list of numbers
156 @param param: The parameter names.
157 @type param: None, str, or list of str
158 @return: A tuple, of length 4, of lists. The first and second elements are the lists of
159 spin specific parameters and values respectively. The third and forth elements
160 are the lists of all other parameters and their values.
161 @rtype: tuple of 4 lists
162 """
163
164
165 is_spin_param = specific_fns.setup.get_specific_fn('is_spin_param', pipes.get_type())
166
167
168 spin_params = []
169 spin_values = []
170 other_params = []
171 other_values = []
172
173
174 if isinstance(param, str):
175
176 if is_spin_param(param):
177 params = spin_params
178 values = spin_values
179
180
181 else:
182 params = other_params
183 values = other_values
184
185
186 if isinstance(val, list) or isinstance(val, ndarray):
187
188 for i in xrange(len(val)):
189 params.append(param)
190
191
192 values = val
193
194
195 else:
196
197 params.append(param)
198
199
200 values.append(val)
201
202
203 elif isinstance(param, list):
204
205 for i in xrange(len(param)):
206
207 if is_spin_param(param[i]):
208 params = spin_params
209 values = spin_values
210
211
212 else:
213 params = other_params
214 values = other_values
215
216
217 params.append(param[i])
218
219
220 if isinstance(val, list) or isinstance(val, ndarray):
221 values.append(val[i])
222 else:
223 values.append(val)
224
225
226
227 return spin_params, spin_values, other_params, other_values
228
229
230 -def read(param=None, scaling=1.0, 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, data_col=None, error_col=None, sep=None, spin_id=None):
231 """Read spin specific data values from a file.
232
233 @keyword param: The name of the parameter to read.
234 @type param: str
235 @keyword scaling: A scaling factor by which all read values are multiplied by.
236 @type scaling: float
237 @keyword file: The name of the file to open.
238 @type file: str
239 @keyword dir: The directory containing the file (defaults to the current directory if None).
240 @type dir: str or None
241 @keyword file_data: An alternative to opening a file, if the data already exists in the correct format. The format is a list of lists where the first index corresponds to the row and the second the column.
242 @type file_data: list of lists
243 @keyword spin_id_col: The column containing the spin ID strings. If supplied, the mol_name_col, res_name_col, res_num_col, spin_name_col, and spin_num_col arguments must be none.
244 @type spin_id_col: int or None
245 @keyword mol_name_col: The column containing the molecule name information. If supplied, spin_id_col must be None.
246 @type mol_name_col: int or None
247 @keyword res_name_col: The column containing the residue name information. If supplied, spin_id_col must be None.
248 @type res_name_col: int or None
249 @keyword res_num_col: The column containing the residue number information. If supplied, spin_id_col must be None.
250 @type res_num_col: int or None
251 @keyword spin_name_col: The column containing the spin name information. If supplied, spin_id_col must be None.
252 @type spin_name_col: int or None
253 @keyword spin_num_col: The column containing the spin number information. If supplied, spin_id_col must be None.
254 @type spin_num_col: int or None
255 @keyword data_col: The column containing the RDC data in Hz.
256 @type data_col: int or None
257 @keyword error_col: The column containing the RDC errors.
258 @type error_col: int or None
259 @keyword sep: The column separator which, if None, defaults to whitespace.
260 @type sep: str or None
261 @keyword spin_id: The spin ID string.
262 @type spin_id: None or str
263 """
264
265
266 pipes.test()
267
268
269 if not exists_mol_res_spin_data():
270 raise RelaxNoSequenceError
271
272
273 if minimise.return_data_name(param):
274
275 min_stat = True
276
277
278 return_value = minimise.return_value
279
280
281 set_fn = minimise.set
282
283
284 else:
285
286 min_stat = False
287
288
289 return_value = specific_fns.setup.get_specific_fn('return_value', pipes.get_type())
290
291
292 set_fn = set
293
294
295 for spin in spin_loop():
296
297 if not spin.select:
298 continue
299
300
301 value, error = return_value(spin, param)
302
303
304 if value != None or error != None:
305 raise RelaxValueError(param)
306
307
308 mol_names = []
309 res_nums = []
310 res_names = []
311 spin_nums = []
312 spin_names = []
313 values = []
314 errors = []
315 for data 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, data_col=data_col, error_col=error_col, sep=sep, spin_id=spin_id):
316
317 if data_col and error_col:
318 mol_name, res_num, res_name, spin_num, spin_name, value, error = data
319 elif data_col:
320 mol_name, res_num, res_name, spin_num, spin_name, value = data
321 error = None
322 else:
323 mol_name, res_num, res_name, spin_num, spin_name, error = data
324 value = None
325
326
327 id = generate_spin_id(mol_name=mol_name, res_num=res_num, res_name=res_name, spin_num=spin_num, spin_name=spin_name)
328 set_fn(val=value, error=error, param=param, spin_id=id)
329
330
331 mol_names.append(mol_name)
332 res_nums.append(res_num)
333 res_names.append(res_name)
334 spin_nums.append(spin_num)
335 spin_names.append(spin_name)
336 values.append(value)
337 errors.append(error)
338
339
340 write_spin_data(file=sys.stdout, mol_names=mol_names, res_nums=res_nums, res_names=res_names, spin_nums=spin_nums, spin_names=spin_names, data=values, data_name=param, error=errors, error_name='%s_error'%param)
341
342
343 if not min_stat:
344 minimise.reset_min_stats()
345
346
347 -def set(val=None, param=None, error=None, pipe=None, spin_id=None, force=True, reset=True):
348 """Set global or spin specific data values.
349
350 @keyword val: The parameter values.
351 @type val: None or list
352 @keyword param: The parameter names.
353 @type param: None, str, or list of str
354 @keyword error: The parameter errors.
355 @type error: None, number, or list of numbers
356 @keyword pipe: The data pipe the values should be placed in.
357 @type pipe: None or str
358 @keyword spin_id: The spin identification string.
359 @type spin_id: str
360 @keyword force: A flag forcing the overwriting of current values.
361 @type force: bool
362 @keyword reset: A flag which if True will cause all minimisation statistics to be reset.
363 @type reset: bool
364 """
365
366
367 if pipe:
368 orig_pipe = pipes.cdp_name()
369 pipes.switch(pipe)
370
371
372 pipes.test()
373
374
375 default_value = specific_fns.setup.get_specific_fn('default_value', pipes.get_type())
376 get_param_names = specific_fns.setup.get_specific_fn('get_param_names', pipes.get_type())
377 return_data_name = specific_fns.setup.get_specific_fn('return_data_name', pipes.get_type())
378 set_param_values = specific_fns.setup.get_specific_fn('set_param_values', pipes.get_type())
379
380
381 if isinstance(val, ndarray):
382 val = val.tolist()
383
384
385 if (isinstance(val, float) or isinstance(val, int)) and param == None:
386 raise RelaxError("The combination of a single value '%s' without specifying the parameter name is invalid." % val)
387 if isinstance(val, list) and isinstance(param, str):
388 raise RelaxError("Invalid combination: When multiple values '%s' are specified, either no parameters or a list of parameters must by supplied rather than the single parameter '%s'." % (val, param))
389
390
391 if isinstance(val, list) and isinstance(param, list) and len(val) != len(param):
392 raise RelaxError("Both the value array and parameter array must be of equal length.")
393
394
395 if param == None:
396 param = get_param_names()
397
398
399 if not isinstance(param, list):
400 param = [param]
401
402
403 if val != None and not isinstance(val, list):
404 val = [val] * len(param)
405
406
407 if val == None:
408
409 val = []
410 for i in range(len(param)):
411 val.append(default_value(return_data_name(param[i])))
412
413
414 if val[-1] == None:
415 raise RelaxParamSetError(param[i])
416
417
418 set_param_values(param=param, value=val, spin_id=spin_id, force=force)
419
420
421 if reset:
422 minimise.reset_min_stats()
423
424
425 if pipe:
426 pipes.switch(orig_pipe)
427
428
429 -def write(param=None, file=None, dir=None, bc=False, force=False, return_value=None):
430 """Write data to a file.
431
432 @keyword param: The name of the parameter to write to file.
433 @type param: str
434 @keyword file: The file to write the data to.
435 @type file: str
436 @keyword dir: The name of the directory to place the file into (defaults to the
437 current directory).
438 @type dir: str
439 @keyword bc: A flag which if True will cause the back calculated values to be written.
440 @type bc: bool
441 @keyword force: A flag which if True will cause any pre-existing file to be overwritten.
442 @type force: bool
443 @keyword return_value: An optional function which if supplied will override the default value
444 returning function.
445 @type return_value: None or func
446 """
447
448
449 pipes.test()
450
451
452 if not exists_mol_res_spin_data():
453 raise RelaxNoSequenceError
454
455
456 file_path = get_file_path(file, dir)
457 file = open_write_file(file, dir, force)
458
459
460 write_data(param, file, bc, return_value)
461
462
463 file.close()
464
465
466 if not hasattr(cdp, 'result_files'):
467 cdp.result_files = []
468 cdp.result_files.append(['text', 'Text', file_path])
469 status.observers.result_file.notify()
470
471
472 -def write_data(param=None, file=None, bc=False, return_value=None):
473 """The function which actually writes the data.
474
475 @keyword param: The parameter to write.
476 @type param: str
477 @keyword file: The file to write the data to.
478 @type file: str
479 @keyword bc: A flag which if True will cause the back calculated values to be written.
480 @type bc: bool
481 @keyword return_value: An optional function which if supplied will override the default value returning function.
482 @type return_value: None or func
483 """
484
485
486 if not return_value:
487 return_value = specific_fns.setup.get_specific_fn('return_value', pipes.get_type())
488
489
490 format = "%-30s%-30s"
491
492
493 mol_names = []
494 res_nums = []
495 res_names = []
496 spin_nums = []
497 spin_names = []
498 values = []
499 errors = []
500
501
502 for spin, mol_name, res_num, res_name in spin_loop(full_info=True):
503
504 value, error = return_value(spin, param, bc=bc)
505
506
507 mol_names.append(mol_name)
508 res_nums.append(res_num)
509 res_names.append(res_name)
510 spin_nums.append(spin.num)
511 spin_names.append(spin.name)
512 values.append(value)
513 errors.append(error)
514
515
516 write_spin_data(file, mol_names=mol_names, res_nums=res_nums, res_names=res_names, spin_nums=spin_nums, spin_names=spin_names, data=values, data_name='value', error=errors, error_name='error')
517