1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 """Module for the manipulation of relaxation data."""
24
25
26 from numpy import int32, ones, zeros
27 import string
28 import sys
29 from warnings import warn
30
31
32 from data_store import Relax_data_store; ds = Relax_data_store()
33 from data_store.exp_info import ExpInfo
34 from lib.errors import RelaxError, RelaxMultiSpinIDError, RelaxNoRiError, RelaxNoSequenceError, RelaxNoSpinError, RelaxRiError
35 from lib.io import write_data
36 from lib.physical_constants import element_from_isotope, number_from_isotope
37 from lib.sequence import read_spin_data
38 from lib.warnings import RelaxWarning
39 from pipe_control import bmrb, pipes, value
40 from pipe_control.interatomic import define, return_interatom, return_interatom_list
41 from pipe_control.mol_res_spin import Selection, exists_mol_res_spin_data, find_index, generate_spin_id_unique, get_molecule_names, return_spin, return_spin_from_selection, spin_index_loop, spin_loop
42 from pipe_control.pipes import check_pipe
43 from pipe_control.spectrometer import copy_frequencies, delete_frequencies, frequency_checks, loop_frequencies, set_frequency
44 from specific_analyses.api import return_api
45
46
47
48 VALID_TYPES = ['R1', 'R2', 'NOE', 'R2eff']
49
50
51
52 -def back_calc(ri_id=None, ri_type=None, frq=None):
53 """Back calculate the relaxation data.
54
55 If no relaxation data currently exists, then the ri_id, ri_type, and frq args are required.
56
57
58 @keyword ri_id: The relaxation data ID string. If not given, all relaxation data will be back calculated.
59 @type ri_id: None or str
60 @keyword ri_type: The relaxation data type. This should be one of 'R1', 'R2', or 'NOE'.
61 @type ri_type: None or str
62 @keyword frq: The spectrometer proton frequency in Hz.
63 @type frq: None or float
64 """
65
66
67 check_pipe()
68
69
70 if not exists_mol_res_spin_data():
71 raise RelaxNoSequenceError
72
73
74 if ri_id and (not hasattr(cdp, 'ri_ids') or ri_id not in cdp.ri_ids) and (ri_type == None or frq == None):
75 raise RelaxError("The 'ri_type' and 'frq' arguments must be supplied as no relaxation data corresponding to '%s' exists." % ri_id)
76
77
78 if ri_type and ri_type not in VALID_TYPES:
79 raise RelaxError("The relaxation data type '%s' must be one of %s." % (ri_type, VALID_TYPES))
80
81
82 frequency_checks(frq)
83
84
85 if not hasattr(cdp, 'ri_type'):
86 cdp.ri_type = {}
87 if not hasattr(cdp, 'ri_ids'):
88 cdp.ri_ids = []
89
90
91 if ri_id and ri_id not in cdp.ri_ids:
92 cdp.ri_ids.append(ri_id)
93 cdp.ri_type[ri_id] = ri_type
94 set_frequency(id=ri_id, frq=frq)
95
96
97 api = return_api()
98
99
100 if ri_id == None:
101 ri_ids = cdp.ri_ids
102 else:
103 ri_ids = [ri_id]
104
105
106 if ri_type == None:
107 ri_types = cdp.ri_type
108 else:
109 ri_types = {ri_id: ri_type}
110
111
112 if frq == None:
113 frqs = cdp.spectrometer_frq
114 else:
115 frqs = {ri_id: frq}
116
117
118 for spin, spin_id in spin_loop(return_id=True):
119
120 if not spin.select:
121 continue
122
123
124 spin_index = find_index(spin_id)
125
126
127 if not hasattr(spin, 'ri_data_bc'):
128 spin.ri_data_bc = {}
129
130
131 for ri_id in ri_ids:
132 spin.ri_data_bc[ri_id] = api.back_calc_ri(spin_index=spin_index, ri_id=ri_id, ri_type=ri_types[ri_id], frq=frqs[ri_id])
133
134
136 """Read the relaxation data from the NMR-STAR dictionary object.
137
138 @param star: The NMR-STAR dictionary object.
139 @type star: NMR_STAR instance
140 @keyword sample_conditions: The sample condition label to read. Only one sample condition can be read per data pipe.
141 @type sample_conditions: None or str
142 """
143
144
145 for data in star.relaxation.loop():
146
147 if 'sample_cond_list_label' in data and sample_conditions and data['sample_cond_list_label'].replace('$', '') != sample_conditions:
148 continue
149
150
151 ri_type = data['data_type']
152 frq = float(data['frq']) * 1e6
153
154
155 frq_label = create_frq_label(float(data['frq']) * 1e6)
156
157
158 ri_id = "%s_%s" % (ri_type, frq_label)
159
160
161 N = bmrb.num_spins(data)
162
163
164 if N == 0:
165 continue
166
167
168 mol_names = bmrb.molecule_names(data, N)
169
170
171 bmrb.generate_sequence(N, spin_names=data['atom_names'], res_nums=data['res_nums'], res_names=data['res_names'], mol_names=mol_names, isotopes=data['isotope'], elements=data['atom_types'])
172
173
174 if 'atom_names_2' in data:
175
176 bmrb.generate_sequence(N, spin_names=data['atom_names_2'], res_nums=data['res_nums'], res_names=data['res_names'], mol_names=mol_names, isotopes=data['isotope_2'], elements=data['atom_types_2'])
177
178
179 for i in range(len(data['atom_names'])):
180
181 spin_id1 = generate_spin_id_unique(spin_name=data['atom_names'][i], res_num=data['res_nums'][i], res_name=data['res_names'][i], mol_name=mol_names[i])
182 spin_id2 = generate_spin_id_unique(spin_name=data['atom_names_2'][i], res_num=data['res_nums'][i], res_name=data['res_names'][i], mol_name=mol_names[i])
183
184
185 if return_interatom(spin_id1=spin_id1, spin_id2=spin_id2):
186 continue
187
188
189 define(spin_id1=spin_id1, spin_id2=spin_id2, verbose=False)
190
191
192 vals = data['data']
193 errors = data['errors']
194 if vals == None:
195 vals = [None] * N
196 if errors == None:
197 errors = [None] * N
198
199
200 if vals != None and 'units' in data:
201
202 if data['units'] == 'ms':
203
204 for i in range(N):
205
206 if vals[i] != None:
207 vals[i] = vals[i] / 1000
208
209
210 if errors[i] != None:
211 errors[i] = errors[i] / 1000
212
213
214 if data['units'] in ['s', 'ms']:
215
216 for i in range(len(vals)):
217
218 if vals[i] != None:
219 vals[i] = 1.0 / vals[i]
220
221
222 if vals[i] != None and errors[i] != None:
223 errors[i] = errors[i] * vals[i]**2
224
225
226 pack_data(ri_id, ri_type, frq, vals, errors, mol_names=mol_names, res_nums=data['res_nums'], res_names=data['res_names'], spin_nums=None, spin_names=data['atom_names'], gen_seq=True, verbose=False)
227
228
229 if data['temp_calibration']:
230 temp_calibration(ri_id=ri_id, method=data['temp_calibration'])
231 if data['temp_control']:
232 temp_control(ri_id=ri_id, method=data['temp_control'])
233
234
235 if data['peak_intensity_type']:
236 peak_intensity_type(ri_id=ri_id, type=data['peak_intensity_type'])
237
238
240 """Generate the relaxation data saveframes for the NMR-STAR dictionary object.
241
242 @param star: The NMR-STAR dictionary object.
243 @type star: NMR_STAR instance
244 """
245
246
247 cdp = pipes.get_pipe()
248
249
250 mol_name_list = []
251 res_num_list = []
252 res_name_list = []
253 atom_name_list = []
254 isotope_list = []
255 element_list = []
256 attached_atom_name_list = []
257 attached_isotope_list = []
258 attached_element_list = []
259 ri_data_list = []
260 ri_data_err_list = []
261 for i in range(len(cdp.ri_ids)):
262 ri_data_list.append([])
263 ri_data_err_list.append([])
264
265
266 labels = cdp.ri_ids
267 exp_label = []
268 spectro_ids = []
269 spectro_labels = []
270
271
272 for spin, mol_name, res_num, res_name, spin_id in spin_loop(full_info=True, return_id=True):
273
274 if not hasattr(spin, 'ri_data'):
275 continue
276
277
278 if res_num == None:
279 raise RelaxError("For the BMRB, the residue of spin '%s' must be numbered." % spin_id)
280 if res_name == None:
281 raise RelaxError("For the BMRB, the residue of spin '%s' must be named." % spin_id)
282 if spin.name == None:
283 raise RelaxError("For the BMRB, the spin '%s' must be named." % spin_id)
284 if spin.isotope == None:
285 raise RelaxError("For the BMRB, the spin isotope type of '%s' must be specified." % spin_id)
286
287
288 mol_name_list.append(mol_name)
289 res_num_list.append(str(res_num))
290 res_name_list.append(str(res_name))
291 atom_name_list.append(str(spin.name))
292
293
294 interatoms = return_interatom_list(spin_id)
295 if len(interatoms) == 0:
296 raise RelaxError("No interatomic interactions are defined for the spin '%s'." % spin_id)
297 if len(interatoms) > 1:
298 raise RelaxError("The BMRB only handles a signal interatomic interaction for the spin '%s'." % spin_id)
299
300
301 spin_attached = return_spin(interatoms[0].spin_id1)
302 if id(spin_attached) == id(spin):
303 spin_attached = return_spin(interatoms[0].spin_id2)
304
305
306 if hasattr(spin_attached, 'name'):
307 attached_atom_name_list.append(str(spin_attached.name))
308 else:
309 attached_atom_name_list.append(None)
310 if hasattr(spin_attached, 'isotope'):
311 attached_element_list.append(element_from_isotope(spin_attached.isotope))
312 attached_isotope_list.append(str(number_from_isotope(spin_attached.isotope)))
313 else:
314 attached_element_list.append(None)
315 attached_isotope_list.append(None)
316
317
318 used_index = -ones(len(cdp.ri_ids))
319 for i in range(len(cdp.ri_ids)):
320
321 if cdp.ri_ids[i] in spin.ri_data:
322 ri_data_list[i].append(str(spin.ri_data[cdp.ri_ids[i]]))
323 ri_data_err_list[i].append(str(spin.ri_data_err[cdp.ri_ids[i]]))
324 else:
325 ri_data_list[i].append(None)
326 ri_data_err_list[i].append(None)
327
328
329 isotope_list.append(int(spin.isotope.strip(string.ascii_letters)))
330 element_list.append(spin.element)
331
332
333 entity_ids = zeros(len(mol_name_list), int32)
334 mol_names = get_molecule_names()
335 for i in range(len(mol_name_list)):
336 for j in range(len(mol_names)):
337 if mol_name_list[i] == mol_names[j]:
338 entity_ids[i] = j+1
339
340
341 if not hasattr(cdp, 'exp_info') or not hasattr(cdp.exp_info, 'temp_calibration'):
342 raise RelaxError("The temperature calibration methods have not been specified.")
343 if not hasattr(cdp, 'exp_info') or not hasattr(cdp.exp_info, 'temp_control'):
344 raise RelaxError("The temperature control methods have not been specified.")
345
346
347 if not hasattr(cdp, 'exp_info') or not hasattr(cdp.exp_info, 'peak_intensity_type'):
348 raise RelaxError("The peak intensity types measured for the relaxation data have not been specified.")
349
350
351 for i in range(len(cdp.ri_ids)):
352
353 ri_id = cdp.ri_ids[i]
354 ri_type = cdp.ri_type[ri_id]
355
356
357 frq = cdp.spectrometer_frq[ri_id] * 1e-6
358
359
360 temp_calib = cdp.exp_info.temp_calibration[ri_id]
361 temp_control = cdp.exp_info.temp_control[ri_id]
362
363
364 peak_intensity_type = cdp.exp_info.peak_intensity_type[ri_id]
365
366
367 if not temp_calib:
368 raise RelaxError("The temperature calibration method for the '%s' relaxation data ID string has not been specified." % ri_id)
369 if not temp_control:
370 raise RelaxError("The temperature control method for the '%s' relaxation data ID string has not been specified." % ri_id)
371
372
373 star.relaxation.add(data_type=ri_type, frq=frq, entity_ids=entity_ids, res_nums=res_num_list, res_names=res_name_list, atom_names=atom_name_list, atom_types=element_list, isotope=isotope_list, entity_ids_2=entity_ids, res_nums_2=res_num_list, res_names_2=res_name_list, atom_names_2=attached_atom_name_list, atom_types_2=attached_element_list, isotope_2=attached_isotope_list, data=ri_data_list[i], errors=ri_data_err_list[i], temp_calibration=temp_calib, temp_control=temp_control, peak_intensity_type=peak_intensity_type)
374
375
376 if ri_type == 'NOE':
377 exp_name = 'steady-state NOE'
378 else:
379 exp_name = ri_type
380 exp_label.append("%s MHz %s" % (frq, exp_name))
381
382
383 frq_num = 1
384 for frq in loop_frequencies():
385 if frq == cdp.spectrometer_frq[ri_id]:
386 break
387 frq_num += 1
388 spectro_ids.append(frq_num)
389 spectro_labels.append("$spectrometer_%s" % spectro_ids[-1])
390
391
392 num = 1
393 for frq in loop_frequencies():
394 star.nmr_spectrometer.add(name="$spectrometer_%s" % num, manufacturer=None, model=None, frq=int(frq/1e6))
395 num += 1
396
397
398 star.experiment.add(name=exp_label, spectrometer_ids=spectro_ids, spectrometer_labels=spectro_labels)
399
400
401 -def copy(pipe_from=None, pipe_to=None, ri_id=None):
402 """Copy the relaxation data from one data pipe to another.
403
404 @keyword pipe_from: The data pipe to copy the relaxation data from. This defaults to the current data pipe.
405 @type pipe_from: str
406 @keyword pipe_to: The data pipe to copy the relaxation data to. This defaults to the current data pipe.
407 @type pipe_to: str
408 @param ri_id: The relaxation data ID string.
409 @type ri_id: str
410 """
411
412
413 if pipe_from == None and pipe_to == None:
414 raise RelaxError("The pipe_from and pipe_to arguments cannot both be set to None.")
415 elif pipe_from == None:
416 pipe_from = pipes.cdp_name()
417 elif pipe_to == None:
418 pipe_to = pipes.cdp_name()
419
420
421 check_pipe(pipe_from)
422 check_pipe(pipe_to)
423
424
425 dp_from = pipes.get_pipe(pipe_from)
426 dp_to = pipes.get_pipe(pipe_to)
427
428
429 if not exists_mol_res_spin_data(pipe_from):
430 raise RelaxNoSequenceError
431
432
433 if not exists_mol_res_spin_data(pipe_to):
434 raise RelaxNoSequenceError
435
436
437 if ri_id and (not hasattr(dp_from, 'ri_ids') or ri_id not in dp_from.ri_ids):
438 raise RelaxNoRiError(ri_id)
439
440
441 if ri_id == None:
442 ri_ids = dp_from.ri_ids
443 else:
444 ri_ids = [ri_id]
445
446
447 if not hasattr(dp_to, 'ri_ids'):
448 dp_to.ri_ids = []
449 if not hasattr(dp_to, 'ri_type'):
450 dp_to.ri_type = {}
451
452
453 for ri_id in ri_ids:
454
455 if ri_id in dp_to.ri_ids:
456 raise RelaxRiError(ri_id)
457
458
459 dp_to.ri_ids.append(ri_id)
460 dp_to.ri_type[ri_id] = dp_from.ri_type[ri_id]
461
462
463 copy_frequencies(pipe_from=pipe_from, pipe_to=pipe_to, id=ri_id)
464
465
466 for mol_index, res_index, spin_index in spin_index_loop():
467
468 spin_from = dp_from.mol[mol_index].res[res_index].spin[spin_index]
469 spin_to = dp_to.mol[mol_index].res[res_index].spin[spin_index]
470
471
472 if not hasattr(spin_from, 'ri_data') and not hasattr(spin_from, 'ri_data_err'):
473 continue
474
475
476 if not hasattr(spin_to, 'ri_data'):
477 spin_to.ri_data = {}
478 if not hasattr(spin_to, 'ri_data_err'):
479 spin_to.ri_data_err = {}
480
481
482 spin_to.ri_data[ri_id] = spin_from.ri_data[ri_id]
483 spin_to.ri_data_err[ri_id] = spin_from.ri_data_err[ri_id]
484
485
487 """Generate a frequency label in MHz, rounded to the nearest factor of 10.
488
489 @param frq: The frequency in Hz.
490 @type frq: float
491 @return: The MHz frequency label.
492 @rtype: str
493 """
494
495
496 label = frq / 1e6
497
498
499 label = int(round(label/10)*10)
500
501
502 return str(label)
503
504
506 """Delete relaxation data corresponding to the relaxation data ID.
507
508 @keyword ri_id: The relaxation data ID string.
509 @type ri_id: str
510 """
511
512
513 check_pipe()
514
515
516 if not exists_mol_res_spin_data():
517 raise RelaxNoSequenceError
518
519
520 if ri_id == None:
521 raise RelaxError("The relaxation data ID string must be supplied.")
522
523
524 if not hasattr(cdp, 'ri_ids') or ri_id not in cdp.ri_ids:
525 raise RelaxNoRiError(ri_id)
526
527
528 cdp.ri_ids.pop(cdp.ri_ids.index(ri_id))
529 del cdp.ri_type[ri_id]
530
531
532 if len(cdp.ri_ids) == 0:
533 del cdp.ri_ids
534 if len(cdp.ri_type) == 0:
535 del cdp.ri_type
536
537
538 for spin in spin_loop():
539
540 if hasattr(spin, 'ri_data') and ri_id in spin.ri_data:
541 del spin.ri_data[ri_id]
542 if hasattr(spin, 'ri_data_err') and ri_id in spin.ri_data_err:
543 del spin.ri_data_err[ri_id]
544
545
546 if hasattr(spin, 'ri_data') and len(spin.ri_data) == 0:
547 del spin.ri_data
548 if hasattr(spin, 'ri_data_err') and len(spin.ri_data_err) == 0:
549 del spin.ri_data_err
550
551
552 if hasattr(cdp, 'exp_info') and hasattr(cdp.exp_info, 'temp_calibration') and ri_id in cdp.exp_info.temp_calibration:
553 del cdp.exp_info.temp_calibration[ri_id]
554 if len(cdp.exp_info.temp_calibration) == 0:
555 del cdp.exp_info.temp_calibration
556 if hasattr(cdp, 'exp_info') and hasattr(cdp.exp_info, 'temp_control') and ri_id in cdp.exp_info.temp_control:
557 del cdp.exp_info.temp_control[ri_id]
558 if len(cdp.exp_info.temp_control) == 0:
559 del cdp.exp_info.temp_control
560 if hasattr(cdp, 'exp_info') and hasattr(cdp.exp_info, 'peak_intensity_type') and ri_id in cdp.exp_info.peak_intensity_type:
561 del cdp.exp_info.peak_intensity_type[ri_id]
562 if len(cdp.exp_info.peak_intensity_type) == 0:
563 del cdp.exp_info.peak_intensity_type
564
565
566 delete_frequencies(id=ri_id)
567
568
589
590
592 """Return a list of names of data structures associated with relaxation data.
593
594 Description
595 ===========
596
597 The names are as follows:
598
599 ri_data: Relaxation data.
600
601 ri_data_err: Relaxation data error.
602
603 ri_data_bc: The back calculated relaxation data.
604
605 ri_type: The relaxation data type, i.e. one of ['NOE', 'R1', 'R2']
606
607 frq: NMR frequencies in Hz, eg [600.0 * 1e6, 500.0 * 1e6]
608
609
610 @keyword global_flag: A flag which if True corresponds to the pipe specific data structures and if False corresponds to the spin specific data structures.
611 @type global_flag: bool
612 @keyword sim_names: A flag which if True will add the Monte Carlo simulation object names as well.
613 @type sim_names: bool
614 @return: The list of object names.
615 @rtype: list of str
616 """
617
618
619 names = []
620
621
622 if not sim_names and global_flag:
623 names.append('ri_id')
624 names.append('ri_type')
625 names.append('frq')
626
627
628 if not sim_names and not global_flag:
629 names.append('ri_data')
630 names.append('ri_data_err')
631 names.append('ri_data_bc')
632
633
634 if sim_names and not global_flag:
635 names.append('ri_data_sim')
636
637
638 return names
639
640
642 """Return the list of all relaxation data IDs.
643
644 @return: The list of all relaxation data IDs.
645 @rtype: list of str
646 """
647
648
649 if cdp == None:
650 return []
651
652
653 if not hasattr(cdp, 'ri_ids'):
654 return []
655
656
657 return cdp.ri_ids
658
659
660 -def pack_data(ri_id, ri_type, frq, values, errors, spin_ids=None, mol_names=None, res_nums=None, res_names=None, spin_nums=None, spin_names=None, spin_id=None, gen_seq=False, verbose=True):
661 """Pack the relaxation data into the data pipe and spin containers.
662
663 The values, errors, and spin_ids arguments must be lists of equal length or None. Each element i corresponds to a unique spin.
664
665 @param ri_id: The relaxation data ID string.
666 @type ri_id: str
667 @param ri_type: The relaxation data type, ie 'R1', 'R2', or 'NOE'.
668 @type ri_type: str
669 @param frq: The spectrometer proton frequency in Hz.
670 @type frq: float
671 @keyword values: The relaxation data for each spin.
672 @type values: None or list of float or float array
673 @keyword errors: The relaxation data errors for each spin.
674 @type errors: None or list of float or float array
675 @keyword spin_ids: The list of spin ID strings. If the other spin identifiers are given, i.e. mol_names, res_nums, res_names, spin_nums, and/or spin_names, then this argument is not necessary.
676 @type spin_ids: None or list of str
677 @keyword mol_names: The list of molecule names used for creating the spin IDs (if not given) or for generating the sequence data.
678 @type mol_names: None or list of str
679 @keyword res_nums: The list of residue numbers used for creating the spin IDs (if not given) or for generating the sequence data.
680 @type res_nums: None or list of str
681 @keyword res_names: The list of residue names used for creating the spin IDs (if not given) or for generating the sequence data.
682 @type res_names: None or list of str
683 @keyword spin_nums: The list of spin numbers used for creating the spin IDs (if not given) or for generating the sequence data.
684 @type spin_nums: None or list of str
685 @keyword spin_names: The list of spin names used for creating the spin IDs (if not given) or for generating the sequence data.
686 @type spin_names: None or list of str
687 @keyword gen_seq: A flag which if True will cause the molecule, residue, and spin sequence data to be generated.
688 @type gen_seq: bool
689 @keyword verbose: A flag which if True will cause all relaxation data loaded to be printed out.
690 @type verbose: bool
691 """
692
693
694 N = len(values)
695
696
697 if errors != None and len(errors) != N:
698 raise RelaxError("The length of the errors arg (%s) does not match that of the value arg (%s)." % (len(errors), N))
699 if spin_ids and len(spin_ids) != N:
700 raise RelaxError("The length of the spin ID strings arg (%s) does not match that of the value arg (%s)." % (len(mol_names), N))
701 if mol_names and len(mol_names) != N:
702 raise RelaxError("The length of the molecule names arg (%s) does not match that of the value arg (%s)." % (len(mol_names), N))
703 if res_nums and len(res_nums) != N:
704 raise RelaxError("The length of the residue numbers arg (%s) does not match that of the value arg (%s)." % (len(res_nums), N))
705 if res_names and len(res_names) != N:
706 raise RelaxError("The length of the residue names arg (%s) does not match that of the value arg (%s)." % (len(res_names), N))
707 if spin_nums and len(spin_nums) != N:
708 raise RelaxError("The length of the spin numbers arg (%s) does not match that of the value arg (%s)." % (len(spin_nums), N))
709 if spin_names and len(spin_names) != N:
710 raise RelaxError("The length of the spin names arg (%s) does not match that of the value arg (%s)." % (len(spin_names), N))
711
712
713 if not mol_names:
714 mol_names = [None] * N
715 if not res_nums:
716 res_nums = [None] * N
717 if not res_names:
718 res_names = [None] * N
719 if not spin_nums:
720 spin_nums = [None] * N
721 if not spin_names:
722 spin_names = [None] * N
723 if errors == None:
724 errors = [None] * N
725
726
727 if not spin_ids:
728 spin_ids = []
729 for i in range(N):
730 spin_ids.append(generate_spin_id_unique(spin_num=spin_nums[i], spin_name=spin_names[i], res_num=res_nums[i], res_name=res_names[i], mol_name=mol_names[i]))
731
732
733 if not hasattr(cdp, 'ri_type'):
734 cdp.ri_type = {}
735 if not hasattr(cdp, 'ri_ids'):
736 cdp.ri_ids = []
737
738
739 set_frequency(id=ri_id, frq=frq)
740
741
742 cdp.ri_ids.append(ri_id)
743 cdp.ri_type[ri_id] = ri_type
744
745
746 select_obj = None
747 if spin_id:
748 select_obj = Selection(spin_id)
749
750
751 data = []
752 for i in range(N):
753
754 select_id = spin_ids[i]
755 if spin_id != None:
756 select_id = "%s&%s" % (select_id, spin_id)
757
758
759 match_mol_names, match_res_nums, match_res_names, spins = return_spin_from_selection(select_id, full_info=True, multi=True)
760
761
762 if len(spins) == 0:
763 continue
764
765
766 if len(spins) > 1:
767 if ids:
768 raise RelaxMultiSpinIDError(spin_ids[i], ids)
769 else:
770 raise RelaxMultiSpinIDError(spin_ids[i], ids)
771 if len(spins) == 0:
772 raise RelaxNoSpinError(spin_ids[i])
773
774
775 for j in range(len(spins)):
776
777 if select_obj and not select_obj.contains_spin(spin_num=spins[j].num, spin_name=spins[j].name, res_num=res_nums[j], res_name=res_names[j], mol=mol_names[j]):
778 continue
779
780
781 if not hasattr(spins[j], 'ri_data') or spins[j].ri_data == None:
782 spins[j].ri_data = {}
783 if not hasattr(spins[j], 'ri_data_err') or spins[j].ri_data_err == None:
784 spins[j].ri_data_err = {}
785
786
787 spins[j].ri_data[ri_id] = values[i]
788 spins[j].ri_data_err[ri_id] = errors[i]
789
790
791 data.append([spin_ids[i], repr(values[i]), repr(errors[i])])
792
793
794 if verbose:
795 print("\nThe following %s MHz %s relaxation data with the ID '%s' has been loaded into the relax data store:\n" % (frq/1e6, ri_type, ri_id))
796 write_data(out=sys.stdout, headings=["Spin_ID", "Value", "Error"], data=data)
797
798
800 """Set the type of intensity measured for the peaks.
801
802 @keyword ri_id: The relaxation data ID string.
803 @type ri_id: str
804 @keyword type: The peak intensity type, one of 'height' or 'volume'.
805 @type type: str
806 """
807
808
809 check_pipe()
810
811
812 if not exists_mol_res_spin_data():
813 raise RelaxNoSequenceError
814
815
816 if not hasattr(cdp, 'ri_ids') or ri_id not in cdp.ri_ids:
817 raise RelaxNoRiError(ri_id)
818
819
820 valid = ['height', 'volume']
821 if type not in valid:
822 raise RelaxError("The '%s' peak intensity type is unknown. Please select one of %s." % (type, valid))
823
824
825 if not hasattr(cdp, 'exp_info'):
826 cdp.exp_info = ExpInfo()
827
828
829 cdp.exp_info.setup_peak_intensity_type(ri_id, type)
830
831
832 -def read(ri_id=None, ri_type=None, frq=None, 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):
833 """Read R1, R2, or NOE, or R2eff relaxation data from a file.
834
835 @param ri_id: The relaxation data ID string.
836 @type ri_id: str
837 @param ri_type: The relaxation data type, ie 'R1', 'R2', 'NOE', or 'R2eff'.
838 @type ri_type: str
839 @param frq: The spectrometer proton frequency in Hz.
840 @type frq: float
841 @param file: The name of the file to open.
842 @type file: str
843 @param dir: The directory containing the file (defaults to the current directory if None).
844 @type dir: str or None
845 @param file_data: An alternative 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.
846 @type file_data: list of lists
847 @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.
848 @type spin_id_col: int or None
849 @keyword mol_name_col: The column containing the molecule name information. If supplied, spin_id_col must be None.
850 @type mol_name_col: int or None
851 @keyword res_name_col: The column containing the residue name information. If supplied, spin_id_col must be None.
852 @type res_name_col: int or None
853 @keyword res_num_col: The column containing the residue number information. If supplied, spin_id_col must be None.
854 @type res_num_col: int or None
855 @keyword spin_name_col: The column containing the spin name information. If supplied, spin_id_col must be None.
856 @type spin_name_col: int or None
857 @keyword spin_num_col: The column containing the spin number information. If supplied, spin_id_col must be None.
858 @type spin_num_col: int or None
859 @keyword data_col: The column containing the relaxation data.
860 @type data_col: int or None
861 @keyword error_col: The column containing the relaxation data errors.
862 @type error_col: int or None
863 @keyword sep: The column separator which, if None, defaults to whitespace.
864 @type sep: str or None
865 @keyword spin_id: The spin ID string used to restrict data loading to a subset of all spins.
866 @type spin_id: None or str
867 """
868
869
870 check_pipe()
871
872
873 if not exists_mol_res_spin_data():
874 raise RelaxNoSequenceError
875
876
877 if hasattr(cdp, 'ri_ids') and ri_id in cdp.ri_ids:
878 raise RelaxError("The relaxation ID string '%s' already exists." % ri_id)
879
880
881 if ri_type not in VALID_TYPES:
882 raise RelaxError("The relaxation data type '%s' must be one of %s." % (ri_type, VALID_TYPES))
883
884
885 frequency_checks(frq)
886
887
888 values = []
889 errors = []
890 mol_names = []
891 res_nums = []
892 res_names = []
893 spin_nums = []
894 spin_names = []
895 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):
896
897 if data_col and error_col:
898 mol_name, res_num, res_name, spin_num, spin_name, value, error = data
899 elif data_col:
900 mol_name, res_num, res_name, spin_num, spin_name, value = data
901 error = None
902 else:
903 mol_name, res_num, res_name, spin_num, spin_name, error = data
904 value = None
905
906
907 if value == None and error == None:
908 continue
909
910
911 mol_names.append(mol_name)
912 res_nums.append(res_num)
913 res_names.append(res_name)
914 spin_nums.append(spin_num)
915 spin_names.append(spin_name)
916 values.append(value)
917 errors.append(error)
918
919
920 pack_data(ri_id, ri_type, frq, values, errors, mol_names=mol_names, res_nums=res_nums, res_names=res_names, spin_nums=spin_nums, spin_names=spin_names, spin_id=spin_id)
921
922
924 """Return a description of the spin specific object.
925
926 @param name: The name of the spin specific object.
927 @type name: str
928 """
929
930 if name == 'ri_data':
931 return 'The relaxation data'
932 if name == 'ri_data_err':
933 return 'The relaxation data errors'
934
935
937 """Return the value and error corresponding to 'data_type'.
938
939 @param spin: The spin container.
940 @type spin: SpinContainer instance
941 @param data_type: The relaxation data ID string.
942 @type data_type: str
943 @keyword bc: A flag which if True will cause the back calculated relaxation data to be written.
944 @type bc: bool
945 """
946
947
948 data = None
949 if not bc and hasattr(spin, 'ri_data') and spin.ri_data != None and data_type in spin.ri_data:
950 data = spin.ri_data[data_type]
951
952
953 if bc and hasattr(spin, 'ri_data_bc') and spin.ri_data_bc != None and data_type in spin.ri_data_bc:
954 data = spin.ri_data_bc[data_type]
955
956
957 error = None
958 if hasattr(spin, 'ri_data_err') and spin.ri_data_err != None and data_type in spin.ri_data_err:
959 error = spin.ri_data_err[data_type]
960
961
962 return data, error
963
964
966 """Set the temperature calibration method.
967
968 @keyword ri_id: The relaxation data type, ie 'R1', 'R2', or 'NOE'.
969 @type ri_id: str
970 @keyword method: The temperature calibration method.
971 @type method: str
972 """
973
974
975 check_pipe()
976
977
978 if not exists_mol_res_spin_data():
979 raise RelaxNoSequenceError
980
981
982 if not hasattr(cdp, 'ri_ids') or ri_id not in cdp.ri_ids:
983 raise RelaxNoRiError(ri_id)
984
985
986 valid = ['methanol', 'monoethylene glycol', 'no calibration applied']
987 if method not in valid:
988 warn(RelaxWarning("The '%s' method is unknown. Please try to use one of %s." % (method, valid)))
989
990
991 if not hasattr(cdp, 'exp_info'):
992 cdp.exp_info = ExpInfo()
993
994
995 cdp.exp_info.temp_calibration_setup(ri_id, method)
996
997
999 """Set the temperature control method.
1000
1001 @keyword ri_id: The relaxation data ID string.
1002 @type ri_id: str
1003 @keyword method: The temperature control method.
1004 @type method: str
1005 """
1006
1007
1008 check_pipe()
1009
1010
1011 if not exists_mol_res_spin_data():
1012 raise RelaxNoSequenceError
1013
1014
1015 if not hasattr(cdp, 'ri_ids') or ri_id not in cdp.ri_ids:
1016 raise RelaxNoRiError(ri_id)
1017
1018
1019 valid = ['single scan interleaving', 'temperature compensation block', 'single scan interleaving and temperature compensation block', 'single fid interleaving', 'single experiment interleaving', 'no temperature control applied']
1020 if method not in valid:
1021 raise RelaxError("The '%s' method is unknown. Please select one of %s." % (method, valid))
1022
1023
1024 if not hasattr(cdp, 'exp_info'):
1025 cdp.exp_info = ExpInfo()
1026
1027
1028 cdp.exp_info.temp_control_setup(ri_id, method)
1029
1030
1031 -def type(ri_id=None, ri_type=None):
1032 """Set or reset the frequency associated with the ID.
1033
1034 @param ri_id: The relaxation data ID string.
1035 @type ri_id: str
1036 @param ri_type: The relaxation data type, ie 'R1', 'R2', or 'NOE'.
1037 @type ri_type: str
1038 """
1039
1040
1041 check_pipe()
1042
1043
1044 if not exists_mol_res_spin_data():
1045 raise RelaxNoSequenceError
1046
1047
1048 if not hasattr(cdp, 'ri_ids') or ri_id not in cdp.ri_ids:
1049 raise RelaxNoRiError(ri_id)
1050
1051
1052 if ri_type not in VALID_TYPES:
1053 raise RelaxError("The relaxation data type '%s' must be one of %s." % (ri_type, VALID_TYPES))
1054
1055
1056 if not hasattr(cdp, 'ri_type'):
1057 cdp.ri_type = {}
1058
1059
1060 cdp.ri_type[ri_id] = ri_type
1061
1062
1063 -def write(ri_id=None, file=None, dir=None, bc=False, force=False):
1064 """Write relaxation data to a file.
1065
1066 @keyword ri_id: The relaxation data ID string.
1067 @type ri_id: str
1068 @keyword file: The name of the file to create.
1069 @type file: str
1070 @keyword dir: The directory to write to.
1071 @type dir: str or None
1072 @keyword bc: A flag which if True will cause the back calculated relaxation data to be written.
1073 @type bc: bool
1074 @keyword force: A flag which if True will cause any pre-existing file to be overwritten.
1075 @type force: bool
1076 """
1077
1078
1079 check_pipe()
1080
1081
1082 if not exists_mol_res_spin_data():
1083 raise RelaxNoSequenceError
1084
1085
1086 if not hasattr(cdp, 'ri_ids') or ri_id not in cdp.ri_ids:
1087 raise RelaxNoRiError(ri_id)
1088
1089
1090 if file == None:
1091 file = ri_id + ".out"
1092
1093
1094 value.write(param=ri_id, file=file, dir=dir, bc=bc, force=force, return_value=return_value, return_data_desc=return_data_desc)
1095