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