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