Package generic_fns :: Module relax_data
[hide private]
[frames] | no frames]

Source Code for Module generic_fns.relax_data

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2003-2011 Edward d'Auvergne                                   # 
  4  #                                                                             # 
  5  # This file is part of the program relax.                                     # 
  6  #                                                                             # 
  7  # relax is free software; you can redistribute it and/or modify               # 
  8  # it under the terms of the GNU General Public License as published by        # 
  9  # the Free Software Foundation; either version 2 of the License, or           # 
 10  # (at your option) any later version.                                         # 
 11  #                                                                             # 
 12  # relax is distributed in the hope that it will be useful,                    # 
 13  # but WITHOUT ANY WARRANTY; without even the implied warranty of              # 
 14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               # 
 15  # GNU General Public License for more details.                                # 
 16  #                                                                             # 
 17  # You should have received a copy of the GNU General Public License           # 
 18  # along with relax; if not, write to the Free Software                        # 
 19  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   # 
 20  #                                                                             # 
 21  ############################################################################### 
 22   
 23  # Module docstring. 
 24  """Module for the manipulation of relaxation data.""" 
 25   
 26  # Python module imports. 
 27  from copy import deepcopy 
 28  from numpy import array, float64, int32, ones, zeros 
 29  import string 
 30  import sys 
 31  from warnings import warn 
 32   
 33  # relax module imports. 
 34  from data import Relax_data_store; ds = Relax_data_store() 
 35  from data.exp_info import ExpInfo 
 36  from generic_fns import bmrb 
 37  from generic_fns.mol_res_spin import create_spin, exists_mol_res_spin_data, find_index, generate_spin_id, get_molecule_names, return_spin, spin_index_loop, spin_loop 
 38  from generic_fns import pipes 
 39  from generic_fns import value 
 40  from physical_constants import element_from_isotope, number_from_isotope 
 41  from relax_errors import RelaxError, RelaxNoRiError, RelaxNoSequenceError, RelaxNoSpinError, RelaxRiError 
 42  from relax_io import read_spin_data 
 43  from relax_warnings import RelaxWarning 
 44  import specific_fns 
 45   
 46   
 47  # The relaxation data types supported. 
 48  VALID_TYPES = ['R1', 'R2', 'NOE'] 
 49   
 50   
 51   
52 -def back_calc(ri_id=None, ri_type=None, frq=None):
53 """Back calculate the relaxation data. 54 55 If no relaxation data currently exists, then the ri_id, ri_type, and frq args are required. 56 57 58 @keyword ri_id: The relaxation data ID string. If not given, all relaxation data will be back calculated. 59 @type ri_id: None or str 60 @keyword ri_type: The relaxation data type. This should be one of 'R1', 'R2', or 'NOE'. 61 @type ri_type: None or str 62 @keyword frq: The spectrometer proton frequency in Hz. 63 @type frq: None or float 64 """ 65 66 # Test if the current pipe exists. 67 pipes.test() 68 69 # Test if sequence data is loaded. 70 if not exists_mol_res_spin_data(): 71 raise RelaxNoSequenceError 72 73 # Check that ri_type and frq are supplied if no relaxation data exists. 74 if ri_id and (not hasattr(cdp, 'ri_ids') or ri_id not in cdp.ri_ids) and (ri_type == None or frq == None): 75 raise RelaxError("The 'ri_type' and 'frq' arguments must be supplied as no relaxation data corresponding to '%s' exists." % ri_id) 76 77 # Check if the type is valid. 78 if ri_type and ri_type not in VALID_TYPES: 79 raise RelaxError("The relaxation data type '%s' must be one of %s." % (ri_type, VALID_TYPES)) 80 81 # Initialise the global data for the current pipe if necessary. 82 if not hasattr(cdp, 'frq'): 83 cdp.frq = {} 84 if not hasattr(cdp, 'ri_type'): 85 cdp.ri_type = {} 86 if not hasattr(cdp, 'ri_ids'): 87 cdp.ri_ids = [] 88 89 # Update the global data if needed. 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 cdp.frq[ri_id] = frq 94 95 # Specific Ri back calculate function setup. 96 back_calculate = specific_fns.setup.get_specific_fn('back_calc_ri', pipes.get_type()) 97 98 # The IDs to loop over. 99 if ri_id == None: 100 ri_ids = cdp.ri_ids 101 else: 102 ri_ids = [ri_id] 103 104 # The data types. 105 if ri_type == None: 106 ri_types = cdp.ri_type 107 else: 108 ri_types = {ri_id: ri_type} 109 110 # The frequencies. 111 if frq == None: 112 frqs = cdp.frq 113 else: 114 frqs = {ri_id: frq} 115 116 # Loop over the spins. 117 for spin, spin_id in spin_loop(return_id=True): 118 # Skip deselected spins. 119 if not spin.select: 120 continue 121 122 # The global index. 123 spin_index = find_index(spin_id) 124 125 # Initialise the spin data if necessary. 126 if not hasattr(spin, 'ri_data_bc'): 127 spin.ri_data_bc = {} 128 129 # Back-calculate the relaxation value. 130 for ri_id in ri_ids: 131 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])
132 133
134 -def bmrb_read(star, sample_conditions=None):
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 # Get the relaxation data. 144 for data in star.relaxation.loop(): 145 # Store the keys. 146 keys = data.keys() 147 148 # Sample conditions do not match (remove the $ sign). 149 if 'sample_cond_list_label' in keys and sample_conditions and string.replace(data['sample_cond_list_label'], '$', '') != sample_conditions: 150 continue 151 152 # Create the labels. 153 ri_type = data['data_type'] 154 frq = float(data['frq']) * 1e6 155 156 # Round the label to the nearest factor of 10. 157 frq_label = create_frq_label(float(data['frq']) * 1e6) 158 159 # The ID string. 160 ri_id = "%s_%s" % (ri_type, frq_label) 161 162 # The number of spins. 163 N = bmrb.num_spins(data) 164 165 # No data in the saveframe. 166 if N == 0: 167 continue 168 169 # The molecule names. 170 mol_names = bmrb.molecule_names(data, N) 171 172 # Generate the sequence if needed. 173 bmrb.generate_sequence(N, spin_names=data['atom_names'], res_nums=data['res_nums'], res_names=data['res_names'], mol_names=mol_names) 174 175 # The data and error. 176 vals = data['data'] 177 errors = data['errors'] 178 if vals == None: 179 vals = [None] * N 180 if errors == None: 181 errors = [None] * N 182 183 # Data transformation. 184 if vals != None and 'units' in keys: 185 # Scaling. 186 if data['units'] == 'ms': 187 # Loop over the data. 188 for i in range(N): 189 # The value. 190 if vals[i] != None: 191 vals[i] = vals[i] / 1000 192 193 # The error. 194 if errors[i] != None: 195 errors[i] = errors[i] / 1000 196 197 # Invert. 198 if data['units'] in ['s', 'ms']: 199 # Loop over the data. 200 for i in range(len(vals)): 201 # The value. 202 if vals[i] != None: 203 vals[i] = 1.0 / vals[i] 204 205 # The error. 206 if vals[i] != None and errors[i] != None: 207 errors[i] = errors[i] * vals[i]**2 208 209 # Pack the data. 210 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)
211 212
213 -def bmrb_write(star):
214 """Generate the relaxation data saveframes for the NMR-STAR dictionary object. 215 216 @param star: The NMR-STAR dictionary object. 217 @type star: NMR_STAR instance 218 """ 219 220 # Get the current data pipe. 221 cdp = pipes.get_pipe() 222 223 # Initialise the spin specific data lists. 224 mol_name_list = [] 225 res_num_list = [] 226 res_name_list = [] 227 atom_name_list = [] 228 isotope_list = [] 229 element_list = [] 230 attached_atom_name_list = [] 231 attached_isotope_list = [] 232 attached_element_list = [] 233 ri_data_list = [] 234 ri_data_err_list = [] 235 for i in range(len(cdp.ri_ids)): 236 ri_data_list.append([]) 237 ri_data_err_list.append([]) 238 239 # Relax data labels. 240 labels = cdp.ri_ids 241 exp_label = [] 242 spectro_ids = [] 243 spectro_labels = [] 244 245 # Store the spin specific data in lists for later use. 246 for spin, mol_name, res_num, res_name, spin_id in spin_loop(full_info=True, return_id=True): 247 # Skip deselected spins. 248 if not spin.select: 249 continue 250 251 # Skip spins with no relaxation data. 252 if not hasattr(spin, 'ri_data'): 253 continue 254 255 # Check the data for None (not allowed in BMRB!). 256 if res_num == None: 257 raise RelaxError("For the BMRB, the residue of spin '%s' must be numbered." % spin_id) 258 if res_name == None: 259 raise RelaxError("For the BMRB, the residue of spin '%s' must be named." % spin_id) 260 if spin.name == None: 261 raise RelaxError("For the BMRB, the spin '%s' must be named." % spin_id) 262 if spin.heteronuc_type == None: 263 raise RelaxError("For the BMRB, the spin isotope type of '%s' must be specified." % spin_id) 264 265 # The molecule/residue/spin info. 266 mol_name_list.append(mol_name) 267 res_num_list.append(str(res_num)) 268 res_name_list.append(str(res_name)) 269 atom_name_list.append(str(spin.name)) 270 271 # The attached atom info. 272 if hasattr(spin, 'attached_atom'): 273 attached_atom_name_list.append(str(spin.attached_atom)) 274 else: 275 attached_atom_name_list.append(str(spin.attached_proton)) 276 attached_element_list.append(element_from_isotope(spin.proton_type)) 277 attached_isotope_list.append(str(number_from_isotope(spin.proton_type))) 278 279 # The relaxation data. 280 used_index = -ones(len(cdp.ri_ids)) 281 for i in range(len(cdp.ri_ids)): 282 # Data exists. 283 if cdp.ri_ids[i] in spin.ri_data.keys(): 284 ri_data_list[i].append(str(spin.ri_data[cdp.ri_ids[i]])) 285 ri_data_err_list[i].append(str(spin.ri_data_err[cdp.ri_ids[i]])) 286 else: 287 ri_data_list[i].append(None) 288 ri_data_err_list[i].append(None) 289 290 # Other info. 291 isotope_list.append(int(string.strip(spin.heteronuc_type, string.ascii_letters))) 292 element_list.append(spin.element) 293 294 # Convert the molecule names into the entity IDs. 295 entity_ids = zeros(len(mol_name_list), int32) 296 mol_names = get_molecule_names() 297 for i in range(len(mol_name_list)): 298 for j in range(len(mol_names)): 299 if mol_name_list[i] == mol_names[j]: 300 entity_ids[i] = j+1 301 302 # Check the temperature control methods. 303 if not hasattr(cdp, 'exp_info') or not hasattr(cdp.exp_info, 'temp_calibration'): 304 raise RelaxError("The temperature calibration methods have not been specified.") 305 if not hasattr(cdp, 'exp_info') or not hasattr(cdp.exp_info, 'temp_control'): 306 raise RelaxError("The temperature control methods have not been specified.") 307 308 # Check the peak intensity type. 309 if not hasattr(cdp, 'exp_info') or not hasattr(cdp.exp_info, 'peak_intensity_type'): 310 raise RelaxError("The peak intensity types measured for the relaxation data have not been specified.") 311 312 # Loop over the relaxation data. 313 for i in xrange(len(cdp.ri_ids)): 314 # Alias. 315 ri_id = cdp.ri_ids[i] 316 ri_type = cdp.ri_type[ri_id] 317 318 # Convert to MHz. 319 frq = cdp.frq[ri_id] * 1e-6 320 321 # Get the temperature control methods. 322 temp_calib = cdp.exp_info.temp_calibration[ri_id] 323 temp_control = cdp.exp_info.temp_control[ri_id] 324 325 # Get the peak intensity type. 326 peak_intensity_type = cdp.exp_info.peak_intensity_type[ri_id] 327 328 # Check. 329 if not temp_calib: 330 raise RelaxError("The temperature calibration method for the '%s' relaxation data ID string has not been specified." % ri_id) 331 if not temp_control: 332 raise RelaxError("The temperature control method for the '%s' relaxation data ID string has not been specified." % ri_id) 333 334 # Add the relaxation data. 335 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) 336 337 # The experimental label. 338 if ri_type == 'NOE': 339 exp_name = 'steady-state NOE' 340 else: 341 exp_name = ri_type 342 exp_label.append("%s MHz %s" % (frq, exp_name)) 343 344 # Spectrometer info. 345 frq_num = 1 346 for frq in frq_loop(): 347 if frq == cdp.frq[ri_id]: 348 break 349 frq_num += 1 350 spectro_ids.append(frq_num) 351 spectro_labels.append("$spectrometer_%s" % spectro_ids[-1]) 352 353 # Add the spectrometer info. 354 num = 1 355 for frq in frq_loop(): 356 star.nmr_spectrometer.add(name="$spectrometer_%s" % num, manufacturer=None, model=None, frq=int(frq/1e6)) 357 num += 1 358 359 # Add the experiment saveframe. 360 star.experiment.add(name=exp_label, spectrometer_ids=spectro_ids, spectrometer_labels=spectro_labels)
361 362
363 -def copy(pipe_from=None, pipe_to=None, ri_id=None):
364 """Copy the relaxation data from one data pipe to another. 365 366 @keyword pipe_from: The data pipe to copy the relaxation data from. This defaults to the current data pipe. 367 @type pipe_from: str 368 @keyword pipe_to: The data pipe to copy the relaxation data to. This defaults to the current data pipe. 369 @type pipe_to: str 370 @param ri_id: The relaxation data ID string. 371 @type ri_id: str 372 """ 373 374 # Defaults. 375 if pipe_from == None and pipe_to == None: 376 raise RelaxError("The pipe_from and pipe_to arguments cannot both be set to None.") 377 elif pipe_from == None: 378 pipe_from = pipes.cdp_name() 379 elif pipe_to == None: 380 pipe_to = pipes.cdp_name() 381 382 # Test if the pipe_from and pipe_to data pipes exist. 383 pipes.test(pipe_from) 384 pipes.test(pipe_to) 385 386 # Get the data pipes. 387 dp_from = pipes.get_pipe(pipe_from) 388 dp_to = pipes.get_pipe(pipe_to) 389 390 # Test if pipe_from contains sequence data. 391 if not exists_mol_res_spin_data(pipe_from): 392 raise RelaxNoSequenceError 393 394 # Test if pipe_to contains sequence data. 395 if not exists_mol_res_spin_data(pipe_to): 396 raise RelaxNoSequenceError 397 398 # Test if relaxation data ID string exists for pipe_from. 399 if ri_id and (not hasattr(dp_from, 'ri_ids') or ri_id not in dp_from.ri_ids): 400 raise RelaxNoRiError(ri_id) 401 402 # The IDs. 403 if ri_id == None: 404 ri_ids = dp_from.ri_ids 405 else: 406 ri_ids = [ri_id] 407 408 # Init target pipe global structures. 409 if not hasattr(dp_to, 'ri_ids'): 410 dp_to.ri_ids = [] 411 if not hasattr(dp_to, 'ri_type'): 412 dp_to.ri_type = {} 413 if not hasattr(dp_to, 'frq'): 414 dp_to.frq = {} 415 416 # Loop over the Rx IDs. 417 for ri_id in ri_ids: 418 # Test if relaxation data ID string exists for pipe_to. 419 if ri_id in dp_to.ri_ids: 420 raise RelaxRiError(ri_id) 421 422 # Copy the global data. 423 dp_to.ri_ids.append(ri_id) 424 dp_to.ri_type[ri_id] = dp_from.ri_type[ri_id] 425 dp_to.frq[ri_id] = dp_from.frq[ri_id] 426 427 # Spin loop. 428 for mol_index, res_index, spin_index in spin_index_loop(): 429 # Alias the spin containers. 430 spin_from = dp_from.mol[mol_index].res[res_index].spin[spin_index] 431 spin_to = dp_to.mol[mol_index].res[res_index].spin[spin_index] 432 433 # Initialise the spin data if necessary. 434 if not hasattr(spin_to, 'ri_data'): 435 spin_to.ri_data = {} 436 if not hasattr(spin_to, 'ri_data_err'): 437 spin_to.ri_data_err = {} 438 439 # Copy the value and error from pipe_from. 440 spin_to.ri_data[ri_id] = spin_from.ri_data[ri_id] 441 spin_to.ri_data_err[ri_id] = spin_from.ri_data_err[ri_id]
442 443
444 -def create_frq_label(frq):
445 """Generate a frequency label in MHz, rounded to the nearest factor of 10. 446 447 @param frq: The frequency in Hz. 448 @type frq: float 449 @return: The MHz frequency label. 450 @rtype: str 451 """ 452 453 # Convert to MHz. 454 label = frq / 1e6 455 456 # Rounding to the nearest factor of 10. 457 label = int(round(label/10)*10) 458 459 # Convert to str and return. 460 return str(label)
461 462
463 -def delete(ri_id=None):
464 """Delete relaxation data corresponding to the relaxation data ID. 465 466 @keyword ri_id: The relaxation data ID string. 467 @type ri_id: str 468 """ 469 470 # Test if the current pipe exists. 471 pipes.test() 472 473 # Test if the sequence data is loaded. 474 if not exists_mol_res_spin_data(): 475 raise RelaxNoSequenceError 476 477 # Test if data exists. 478 if not hasattr(cdp, 'ri_ids') or ri_id not in cdp.ri_ids: 479 raise RelaxNoRiError(ri_id) 480 481 # Loop over the spins. 482 for spin in spin_loop(): 483 # Relaxation data and errors. 484 del spin.ri_data[ri_id] 485 del spin.ri_data_err[ri_id]
486 487
488 -def display(ri_id=None):
489 """Display relaxation data corresponding to the ID. 490 491 @keyword ri_id: The relaxation data ID string. 492 @type ri_id: str 493 """ 494 495 # Test if the current pipe exists. 496 pipes.test() 497 498 # Test if the sequence data is loaded. 499 if not exists_mol_res_spin_data(): 500 raise RelaxNoSequenceError 501 502 # Test if data exists. 503 if not hasattr(cdp, 'ri_ids') or ri_id not in cdp.ri_ids: 504 raise RelaxNoRiError(ri_id) 505 506 # Print the data. 507 value.write_data(param=ri_id, file=sys.stdout, return_value=return_value)
508 509
510 -def frq_loop():
511 """Generator function for returning each unique frequency. 512 513 @return: The frequency. 514 @rtype: float 515 """ 516 517 # Init. 518 frq = [] 519 520 # Loop over the Rx data. 521 for ri_id in cdp.ri_ids: 522 # New frequency. 523 if cdp.frq[ri_id] not in frq: 524 # Add the frequency. 525 frq.append(cdp.frq[ri_id]) 526 527 # Yield the value. 528 yield cdp.frq[ri_id]
529 530
531 -def get_data_names(global_flag=False, sim_names=False):
532 """Return a list of names of data structures associated with relaxation data. 533 534 Description 535 =========== 536 537 The names are as follows: 538 539 ri_data: Relaxation data. 540 541 ri_data_err: Relaxation data error. 542 543 ri_data_bc: The back calculated relaxation data. 544 545 ri_type: The relaxation data type, i.e. one of ['NOE', 'R1', 'R2'] 546 547 frq: NMR frequencies in Hz, eg [600.0 * 1e6, 500.0 * 1e6] 548 549 550 @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. 551 @type global_flag: bool 552 @keyword sim_names: A flag which if True will add the Monte Carlo simulation object names as well. 553 @type sim_names: bool 554 @return: The list of object names. 555 @rtype: list of str 556 """ 557 558 # Initialise. 559 names = [] 560 561 # Global data names. 562 if not sim_names and global_flag: 563 names.append('ri_id') 564 names.append('ri_type') 565 names.append('frq') 566 567 # Spin specific data names. 568 if not sim_names and not global_flag: 569 names.append('ri_data') 570 names.append('ri_data_err') 571 names.append('ri_data_bc') 572 573 # Simulation object names. 574 if sim_names and not global_flag: 575 names.append('ri_data_sim') 576 577 # Return the list of names. 578 return names
579 580
581 -def num_frq():
582 """Determine the number of unique frequencies. 583 584 @return: The number of unique frequencies. 585 @rtype: int 586 """ 587 588 # Init. 589 frq = [] 590 count = 0 591 592 # Loop over the Rx data. 593 for ri_id in cdp.ri_ids: 594 # New frequency. 595 if cdp.frq[ri_id] not in frq: 596 # Add the frequency. 597 frq.append(cdp.frq[ri_id]) 598 599 # Increment the counter. 600 count += 1 601 602 # Return the counter. 603 return count
604 605
606 -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, gen_seq=False):
607 """Pack the relaxation data into the data pipe and spin containers. 608 609 The values, errors, and spin_ids arguments must be lists of equal length or None. Each element i corresponds to a unique spin. 610 611 @param ri_id: The relaxation data ID string. 612 @type ri_id: str 613 @param ri_type: The relaxation data type, ie 'R1', 'R2', or 'NOE'. 614 @type ri_type: str 615 @param frq: The spectrometer proton frequency in Hz. 616 @type frq: float 617 @keyword values: The relaxation data for each spin. 618 @type values: None or list of float or float array 619 @keyword errors: The relaxation data errors for each spin. 620 @type errors: None or list of float or float array 621 @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. 622 @type spin_ids: None or list of str 623 @keyword mol_names: The list of molecule names used for creating the spin IDs (if not given) or for generating the sequence data. 624 @type mol_names: None or list of str 625 @keyword res_nums: The list of residue numbers used for creating the spin IDs (if not given) or for generating the sequence data. 626 @type res_nums: None or list of str 627 @keyword res_names: The list of residue names used for creating the spin IDs (if not given) or for generating the sequence data. 628 @type res_names: None or list of str 629 @keyword spin_nums: The list of spin numbers used for creating the spin IDs (if not given) or for generating the sequence data. 630 @type spin_nums: None or list of str 631 @keyword spin_names: The list of spin names used for creating the spin IDs (if not given) or for generating the sequence data. 632 @type spin_names: None or list of str 633 @keyword gen_seq: A flag which if True will cause the molecule, residue, and spin sequence data to be generated. 634 @type gen_seq: bool 635 """ 636 637 # The number of spins. 638 N = len(values) 639 640 # Test the data. 641 if errors != None and len(errors) != N: 642 raise RelaxError("The length of the errors arg (%s) does not match that of the value arg (%s)." % (len(errors), N)) 643 if spin_ids and len(spin_ids) != N: 644 raise RelaxError("The length of the spin ID strings arg (%s) does not match that of the value arg (%s)." % (len(mol_names), N)) 645 if mol_names and len(mol_names) != N: 646 raise RelaxError("The length of the molecule names arg (%s) does not match that of the value arg (%s)." % (len(mol_names), N)) 647 if res_nums and len(res_nums) != N: 648 raise RelaxError("The length of the residue numbers arg (%s) does not match that of the value arg (%s)." % (len(res_nums), N)) 649 if res_names and len(res_names) != N: 650 raise RelaxError("The length of the residue names arg (%s) does not match that of the value arg (%s)." % (len(res_names), N)) 651 if spin_nums and len(spin_nums) != N: 652 raise RelaxError("The length of the spin numbers arg (%s) does not match that of the value arg (%s)." % (len(spin_nums), N)) 653 if spin_names and len(spin_names) != N: 654 raise RelaxError("The length of the spin names arg (%s) does not match that of the value arg (%s)." % (len(spin_names), N)) 655 656 # Generate some empty lists. 657 if not mol_names: 658 mol_names = [None] * N 659 if not res_nums: 660 res_nums = [None] * N 661 if not res_names: 662 res_names = [None] * N 663 if not spin_nums: 664 spin_nums = [None] * N 665 if not spin_names: 666 spin_names = [None] * N 667 if errors == None: 668 errors = [None] * N 669 670 # Generate the spin IDs. 671 if not spin_ids: 672 spin_ids = [] 673 for i in range(N): 674 spin_ids.append(generate_spin_id(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])) 675 676 # Initialise the global data for the current pipe if necessary. 677 if not hasattr(cdp, 'frq'): 678 cdp.frq = {} 679 if not hasattr(cdp, 'ri_type'): 680 cdp.ri_type = {} 681 if not hasattr(cdp, 'ri_ids'): 682 cdp.ri_ids = [] 683 684 # Update the global data. 685 cdp.ri_ids.append(ri_id) 686 cdp.ri_type[ri_id] = ri_type 687 cdp.frq[ri_id] = frq 688 689 # Generate the sequence. 690 if gen_seq: 691 bmrb.generate_sequence(N, spin_ids=spin_ids, spin_nums=spin_nums, spin_names=spin_names, res_nums=res_nums, res_names=res_names, mol_names=mol_names) 692 693 # Loop over the spin data. 694 for i in range(N): 695 # Get the corresponding spin container. 696 spin = return_spin(spin_ids[i]) 697 if spin == None: 698 raise RelaxNoSpinError(spin_ids[i]) 699 700 # Initialise the spin data if necessary. 701 if not hasattr(spin, 'ri_data') or spin.ri_data == None: 702 spin.ri_data = {} 703 if not hasattr(spin, 'ri_data_err') or spin.ri_data_err == None: 704 spin.ri_data_err = {} 705 706 # Update all data structures. 707 spin.ri_data[ri_id] = values[i] 708 spin.ri_data_err[ri_id] = errors[i]
709 710
711 -def peak_intensity_type(ri_id=None, type=None):
712 """Set the type of intensity measured for the peaks. 713 714 @keyword ri_id: The relaxation data ID string. 715 @type ri_id: str 716 @keyword type: The peak intensity type, one of 'height' or 'volume'. 717 @type type: str 718 """ 719 720 # Test if the current pipe exists. 721 pipes.test() 722 723 # Test if sequence data is loaded. 724 if not exists_mol_res_spin_data(): 725 raise RelaxNoSequenceError 726 727 # Test if data exists. 728 if not hasattr(cdp, 'ri_ids') or ri_id not in cdp.ri_ids: 729 raise RelaxNoRiError(ri_id) 730 731 # Check the values, and warn if not in the list. 732 valid = ['height', 'volume'] 733 if type not in valid: 734 raise RelaxError("The '%s' peak intensity type is unknown. Please select one of %s." % (type, valid)) 735 736 # Set up the experimental info data container, if needed. 737 if not hasattr(cdp, 'exp_info'): 738 cdp.exp_info = ExpInfo() 739 740 # Store the type. 741 cdp.exp_info.setup_peak_intensity_type(ri_id, type)
742 743
744 -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):
745 """Read R1, R2, or NOE relaxation data from a file. 746 747 @param ri_id: The relaxation data ID string. 748 @type ri_id: str 749 @param ri_type: The relaxation data type, ie 'R1', 'R2', or 'NOE'. 750 @type ri_type: str 751 @param frq: The spectrometer proton frequency in Hz. 752 @type frq: float 753 @param file: The name of the file to open. 754 @type file: str 755 @param dir: The directory containing the file (defaults to the current directory if None). 756 @type dir: str or None 757 @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. 758 @type file_data: list of lists 759 @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. 760 @type spin_id_col: int or None 761 @keyword mol_name_col: The column containing the molecule name information. If supplied, spin_id_col must be None. 762 @type mol_name_col: int or None 763 @keyword res_name_col: The column containing the residue name information. If supplied, spin_id_col must be None. 764 @type res_name_col: int or None 765 @keyword res_num_col: The column containing the residue number information. If supplied, spin_id_col must be None. 766 @type res_num_col: int or None 767 @keyword spin_name_col: The column containing the spin name information. If supplied, spin_id_col must be None. 768 @type spin_name_col: int or None 769 @keyword spin_num_col: The column containing the spin number information. If supplied, spin_id_col must be None. 770 @type spin_num_col: int or None 771 @keyword data_col: The column containing the relaxation data. 772 @type data_col: int or None 773 @keyword error_col: The column containing the relaxation data errors. 774 @type error_col: int or None 775 @keyword sep: The column separator which, if None, defaults to whitespace. 776 @type sep: str or None 777 @keyword spin_id: The spin ID string used to restrict data loading to a subset of all spins. 778 @type spin_id: None or str 779 """ 780 781 # Test if the current data pipe exists. 782 pipes.test() 783 784 # Test if sequence data exists. 785 if not exists_mol_res_spin_data(): 786 raise RelaxNoSequenceError 787 788 # Test if the ri_id already exists. 789 if hasattr(cdp, 'ri_ids') and ri_id in cdp.ri_ids: 790 raise RelaxError("The relaxation ID string '%s' already exists." % ri_id) 791 792 # Check if the type is valid. 793 if ri_type not in VALID_TYPES: 794 raise RelaxError("The relaxation data type '%s' must be one of %s." % (ri_type, VALID_TYPES)) 795 796 # Loop over the file data to create the data structures for packing. 797 values = [] 798 errors = [] 799 ids = [] 800 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, spin_id=spin_id): 801 # Unpack. 802 if data_col and error_col: 803 id, value, error = data 804 elif data_col: 805 id, value = data 806 error = None 807 else: 808 id, error = data 809 value = None 810 811 # Pack the spin ID info. 812 ids.append(id) 813 814 # Convert the data. 815 values.append(value) 816 errors.append(error) 817 818 # Pack the data. 819 pack_data(ri_id, ri_type, frq, values, errors, ids)
820 821
822 -def return_data_desc(name):
823 """Return a description of the spin specific object. 824 825 @param name: The name of the spin specific object. 826 @type name: str 827 """ 828 829 if name == 'ri_data': 830 return 'The relaxation data' 831 if name == 'ri_data_err': 832 return 'The relaxation data errors'
833 834
835 -def return_value(spin, data_type, bc=False):
836 """Return the value and error corresponding to 'data_type'. 837 838 @param spin: The spin container. 839 @type spin: SpinContainer instance 840 @param data_type: The relaxation data ID string. 841 @type data_type: str 842 @keyword bc: A flag which if True will cause the back calculated relaxation data to be written. 843 @type bc: bool 844 """ 845 846 # Relaxation data. 847 data = None 848 if not bc and hasattr(spin, 'ri_data') and spin.ri_data != None and data_type in spin.ri_data.keys(): 849 data = spin.ri_data[data_type] 850 851 # Back calculated relaxation data 852 if bc and hasattr(spin, 'ri_data_bc') and spin.ri_data_bc != None and data_type in spin.ri_data_bc.keys(): 853 data = spin.ri_data_bc[data_type] 854 855 # Relaxation errors. 856 error = None 857 if hasattr(spin, 'ri_data_err') and spin.ri_data_err != None and data_type in spin.ri_data_err.keys(): 858 error = spin.ri_data_err[data_type] 859 860 # Return the data. 861 return data, error
862 863
864 -def temp_calibration(ri_id=None, method=None):
865 """Set the temperature calibration method. 866 867 @keyword ri_id: The relaxation data type, ie 'R1', 'R2', or 'NOE'. 868 @type ri_id: str 869 @keyword method: The temperature calibration method. 870 @type method: str 871 """ 872 873 # Test if the current pipe exists. 874 pipes.test() 875 876 # Test if sequence data is loaded. 877 if not exists_mol_res_spin_data(): 878 raise RelaxNoSequenceError 879 880 # Test if data exists. 881 if not hasattr(cdp, 'ri_ids') or ri_id not in cdp.ri_ids: 882 raise RelaxNoRiError(ri_id) 883 884 # Check the values, and warn if not in the list. 885 valid = ['methanol', 'monoethylene glycol', 'no calibration applied'] 886 if method not in valid: 887 warn(RelaxWarning("The '%s' method is unknown. Please try to use one of %s." % (method, valid))) 888 889 # Set up the experimental info data container, if needed. 890 if not hasattr(cdp, 'exp_info'): 891 cdp.exp_info = ExpInfo() 892 893 # Store the method. 894 cdp.exp_info.temp_calibration_setup(ri_id, method)
895 896
897 -def temp_control(ri_id=None, method=None):
898 """Set the temperature control method. 899 900 @keyword ri_id: The relaxation data ID string. 901 @type ri_id: str 902 @keyword method: The temperature control method. 903 @type method: str 904 """ 905 906 # Test if the current pipe exists. 907 pipes.test() 908 909 # Test if sequence data is loaded. 910 if not exists_mol_res_spin_data(): 911 raise RelaxNoSequenceError 912 913 # Test if data exists. 914 if not hasattr(cdp, 'ri_ids') or ri_id not in cdp.ri_ids: 915 raise RelaxNoRiError(ri_id) 916 917 # Check the values, and warn if not in the list. 918 valid = ['single scan interleaving', 'temperature compensation block', 'single scan interleaving and temperature compensation block', 'single fid interleaving', 'single experiment interleaving', 'no temperature control applied'] 919 if method not in valid: 920 raise RelaxError("The '%s' method is unknown. Please select one of %s." % (method, valid)) 921 922 # Set up the experimental info data container, if needed. 923 if not hasattr(cdp, 'exp_info'): 924 cdp.exp_info = ExpInfo() 925 926 # Store the method. 927 cdp.exp_info.temp_control_setup(ri_id, method)
928 929
930 -def write(ri_id=None, file=None, dir=None, bc=False, force=False):
931 """Write relaxation data to a file. 932 933 @keyword ri_id: The relaxation data ID string. 934 @type ri_id: str 935 @keyword file: The name of the file to create. 936 @type file: str 937 @keyword dir: The directory to write to. 938 @type dir: str or None 939 @keyword bc: A flag which if True will cause the back calculated relaxation data to be written. 940 @type bc: bool 941 @keyword force: A flag which if True will cause any pre-existing file to be overwritten. 942 @type force: bool 943 """ 944 945 # Test if the current pipe exists. 946 pipes.test() 947 948 # Test if the sequence data is loaded. 949 if not exists_mol_res_spin_data(): 950 raise RelaxNoSequenceError 951 952 # Test if data exists. 953 if not hasattr(cdp, 'ri_ids') or ri_id not in cdp.ri_ids: 954 raise RelaxNoRiError(ri_id) 955 956 # Create the file name if none is given. 957 if file == None: 958 file = ri_id + ".out" 959 960 # Write the data. 961 value.write(param=ri_id, file=file, dir=dir, bc=bc, force=force, return_value=return_value)
962