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