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