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