Package specific_fns :: Package model_free :: Module bmrb
[hide private]
[frames] | no frames]

Source Code for Module specific_fns.model_free.bmrb

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2009-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  # Dependency check module. 
 24  import dep_check 
 25   
 26  # Python module imports. 
 27  from math import pi 
 28  from numpy import int32, zeros 
 29  import string 
 30  from warnings import warn 
 31   
 32  # relax module imports. 
 33  if dep_check.bmrblib_module: 
 34      import bmrblib 
 35  from generic_fns import bmrb, diffusion_tensor, exp_info, mol_res_spin, pipes, relax_data 
 36  from generic_fns.mol_res_spin import get_molecule_names, spin_loop 
 37  from relax_errors import RelaxError 
 38  from relax_warnings import RelaxWarning 
 39   
 40   
41 -class Bmrb:
42 """Class containing methods related to BMRB STAR file reading and writing.""" 43
44 - def _from_bmrb_model(self, name=None):
45 """The model-free model name to BMRB name mapping. 46 47 @keyword name: The BMRB model name. 48 @type name: str 49 @return: The corresponding model-free model name. 50 @rtype: str 51 """ 52 53 # The same name. 54 if name in ['m0', 'm1', 'm2', 'm3', 'm4', 'm5', 'm6', 'm7', 'm8', 'm9', 'm0', 'tm1', 'tm2', 'tm3', 'tm4', 'tm5', 'tm6', 'tm7', 'tm8', 'tm9']: 55 return name 56 57 # Conversion of Modelfree4 (and relax) model numbers. 58 if name in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']: 59 return 'm' + name 60 61 # The BMRB to model-free model name map. 62 map = {'': 'm0', 63 'S2': 'm1', 64 'S2, te': 'm2', 65 'S2, Rex': 'm3', 66 'S2, te, Rex': 'm4', 67 'S2, te, S2f': 'm5', 68 'S2f, S2, ts': 'm5', 69 'S2f, tf, S2, ts': 'm6', 70 'S2f, S2, ts, Rex': 'm7', 71 'S2f, tf, S2, ts, Rex': 'm8', 72 'Rex': 'm9', 73 'tm': 'tm0', 74 'tm, S2': 'tm1', 75 'tm, S2, te': 'tm2', 76 'tm, S2, Rex': 'tm3', 77 'tm, S2, te, Rex': 'tm4', 78 'tm, S2f, S2, ts': 'tm5', 79 'tm, S2f, tf, S2, ts': 'tm6', 80 'tm, S2f, S2, ts, Rex': 'tm7', 81 'tm, S2f, tf, S2, ts, Rex': 'tm8', 82 'tm, Rex': 'tm9' 83 } 84 85 # Loop over the dictionary. 86 for item in map.items(): 87 # Normal match. 88 if item[0] == name: 89 return item[1] 90 91 # No whitespace. 92 if string.replace(item[0], ' ', '') == name: 93 return item[1] 94 95 # Should not be here! 96 if name: 97 raise RelaxError("The BMRB model-free model '%s' is unknown." % name)
98 99
100 - def _sf_model_free_read(self, star, sample_conditions=None):
101 """Fill the spin containers with the model-free data from the saveframe records. 102 103 @param star: The NMR-STAR dictionary object. 104 @type star: NMR_STAR instance 105 @keyword sample_conditions: The sample condition label to read. Only one sample condition can be read per data pipe. 106 @type sample_conditions: None or str 107 """ 108 109 # The list of model-free parameters (both bmrblib names and relax names). 110 mf_bmrb_key = ['bond_length', 'local_tm', 's2', 's2f', 's2s', 'te', 'tf', 'ts', 'rex', 'chi2'] 111 mf_params = ['r', 'local_tm', 's2', 's2f', 's2s', 'te', 'tf', 'ts', 'rex', 'chi2'] 112 113 # Get the entities. 114 for data in star.model_free.loop(): 115 # Store the keys. 116 keys = data.keys() 117 118 # Sample conditions do not match (remove the $ sign). 119 if 'sample_cond_list_label' in keys and sample_conditions and string.replace(data['sample_cond_list_label'], '$', '') != sample_conditions: 120 continue 121 122 # Global data. 123 if 'global_chi2' in keys: 124 setattr(cdp, 'chi2', data['global_chi2']) 125 126 # The number of spins. 127 N = bmrb.num_spins(data) 128 129 # No data in the saveframe. 130 if N == 0: 131 continue 132 133 # The molecule names. 134 mol_names = bmrb.molecule_names(data, N) 135 136 # Missing atom names. 137 if 'atom_names' not in keys or data['atom_names'] == None: 138 data['atom_names'] = [None] * N 139 140 # Generate the sequence if needed. 141 bmrb.generate_sequence(N, spin_names=data['atom_names'], res_nums=data['res_nums'], res_names=data['res_names'], mol_names=mol_names) 142 143 # Correlation time scaling. 144 table = {'s': 1.0, 145 'ns': 1e-9, 146 'ps': 1e-12} 147 te_scale = 1.0 148 if data['te_units']: 149 te_scale = table[data['te_units']] 150 151 # Fast correlation time scaling. 152 if data['tf_units']: 153 tf_scale = table[data['tf_units']] 154 else: 155 tf_scale = te_scale 156 157 # Slow correlation time scaling. 158 if data['ts_units']: 159 ts_scale = table[data['ts_units']] 160 else: 161 ts_scale = te_scale 162 163 # Rex scaling. 164 rex_scale = 1.0 165 if hasattr(cdp, 'frq') and len(cdp.frq): 166 rex_scale = 1.0 / (2.0*pi*cdp.frq[cdp.ri_ids[0]])**2 167 168 # Loop over the spins. 169 for i in range(N): 170 # Generate a spin ID. 171 spin_id = mol_res_spin.generate_spin_id(mol_name=mol_names[i], res_name=data['res_names'][i], res_num=data['res_nums'][i], spin_name=data['atom_names'][i]) 172 173 # Obtain the spin. 174 spin = mol_res_spin.return_spin(spin_id) 175 176 # No spin?!? 177 if spin == None: 178 raise(RelaxError("The spin '%s' does not exist." % spin_id)) 179 180 # Loop over and set the model-free parameters. 181 for j in range(len(mf_params)): 182 # The parameter. 183 param = mf_params[j] 184 185 # No parameter. 186 if not mf_bmrb_key[j] in keys: 187 continue 188 189 # The parameter and its value. 190 if data[mf_bmrb_key[j]] != None: 191 # The value. 192 value = data[mf_bmrb_key[j]][i] 193 194 # Parameter scaling. 195 if value != None: 196 if param == 'te': 197 value = value * te_scale 198 elif param == 'tf': 199 value = value * tf_scale 200 elif param == 'ts': 201 value = value * ts_scale 202 elif param == 'rex': 203 value = value * rex_scale 204 205 # No parameter value. 206 else: 207 value = None 208 209 # Set the parameter. 210 setattr(spin, param, value) 211 212 # The error. 213 mf_bmrb_key_err = mf_bmrb_key[j] + '_err' 214 error = None 215 if mf_bmrb_key_err in keys and data[mf_bmrb_key_err] != None: 216 error = data[mf_bmrb_key_err][i] 217 218 # Error scaling. 219 if error != None: 220 if param == 'te': 221 error = error * te_scale 222 elif param == 'tf': 223 error = error * tf_scale 224 elif param == 'ts': 225 error = error * ts_scale 226 elif param == 'rex': 227 error = error * rex_scale 228 229 # Set the error. 230 mf_param_err = param + '_err' 231 if mf_bmrb_key_err in keys and data[mf_bmrb_key_err] != None: 232 setattr(spin, mf_param_err, error) 233 234 # The model. 235 if data['model_fit'] != None and data['model_fit'][i] != None: 236 model = self._from_bmrb_model(data['model_fit'][i]) 237 setattr(spin, 'model', model) 238 239 # The equation and parameters. 240 equation, params = self._model_map(model) 241 setattr(spin, 'equation', equation) 242 setattr(spin, 'params', params) 243 244 # Convert te values which should be ts! 245 if hasattr(spin, 'model') and spin.model in ['m5', 'm6', 'm7', 'm8'] and hasattr(spin, 'te') and spin.te != None: 246 # Change the parameter name of te to ts. 247 spin.ts = spin.te 248 if hasattr(spin, 'te_err'): 249 spin.ts_err = spin.te_err 250 251 # Set the te and te_err values to None. 252 spin.te = None 253 spin.te_err = None 254 255 # The element. 256 if'atom_types' in keys and data['atom_types'] != None: 257 setattr(spin, 'element', data['atom_types'][i]) 258 259 # Heteronucleus type. 260 if'atom_types' in keys and data['atom_types'] != None and data['atom_types'][i] != None and 'isotope' in keys and data['isotope'] != None: 261 # The isotope number. 262 iso_num = data['isotope'][i] 263 264 # No isotope number. 265 iso_table = {'C': 13, 'N': 15} 266 if not data['isotope'][i]: 267 iso_num = iso_table[data['atom_types'][i]] 268 269 # Set the type. 270 setattr(spin, 'heteronuc_type', str(iso_num) + data['atom_types'][i])
271 272
273 - def _sf_csa_read(self, star):
274 """Place the CSA data from the saveframe records into the spin container. 275 276 @param star: The NMR-STAR dictionary object. 277 @type star: NMR_STAR instance 278 """ 279 280 # Get the entities. 281 for data in star.chem_shift_anisotropy.loop(): 282 # Loop over the spins. 283 for i in range(len(data['data_ids'])): 284 # Generate a spin ID. 285 spin_id = mol_res_spin.generate_spin_id(res_num=data['res_nums'][i], spin_name=data['atom_names'][i]) 286 287 # Obtain the spin. 288 spin = mol_res_spin.return_spin(spin_id) 289 290 # The CSA value (converted from ppm). 291 setattr(spin, 'csa', data['csa'][i] * 1e-6)
292 293
294 - def _to_bmrb_model(self, name=None):
295 """Convert the model-free model name to the BMRB name. 296 297 @keyword name: The model-free model name. 298 @type name: str 299 @return: The corresponding BMRB model name. 300 @rtype: str 301 """ 302 303 # The relax to BMRB model-free model name map. 304 map = {'m0': '', 305 'm1': 'S2', 306 'm2': 'S2, te', 307 'm3': 'S2, Rex', 308 'm4': 'S2, te, Rex', 309 'm5': 'S2f, S2, ts', 310 'm6': 'S2f, tf, S2, ts', 311 'm7': 'S2f, S2, ts, Rex', 312 'm8': 'S2f, tf, S2, ts, Rex', 313 'm9': 'Rex', 314 'tm0': 'tm', 315 'tm1': 'tm, S2', 316 'tm2': 'tm, S2, te', 317 'tm3': 'tm, S2, Rex', 318 'tm4': 'tm, S2, te, Rex', 319 'tm5': 'tm, S2f, S2, ts', 320 'tm6': 'tm, S2f, tf, S2, ts', 321 'tm7': 'tm, S2f, S2, ts, Rex', 322 'tm8': 'tm, S2f, tf, S2, ts, Rex', 323 'tm9': 'tm, Rex' 324 } 325 326 # No match. 327 if name not in map.keys(): 328 raise RelaxError("The model-free model '%s' is unknown." % name) 329 330 # Return the BMRB model name. 331 return map[name]
332 333
334 - def bmrb_read(self, file_path, version=None, sample_conditions=None):
335 """Read the model-free results from a BMRB NMR-STAR v3.1 formatted file. 336 337 @param file_path: The full file path. 338 @type file_path: str 339 @keyword version: The BMRB version to force the reading. 340 @type version: None or str 341 @keyword sample_conditions: The sample condition label to read. Only one sample condition can be read per data pipe. 342 @type sample_conditions: None or str 343 """ 344 345 # Initialise the NMR-STAR data object. 346 star = bmrblib.create_nmr_star('relax_model_free_results', file_path, version) 347 348 # Read the contents of the STAR formatted file. 349 star.read() 350 351 # The sample conditions. 352 sample_conds = bmrb.list_sample_conditions(star) 353 if sample_conditions and sample_conditions not in sample_conds: 354 raise RelaxError("The sample conditions label '%s' does not correspond to any of the labels in the file: %s" % (sample_conditions, sample_conds)) 355 if not sample_conditions and len(sample_conds) > 1: 356 raise RelaxError("Only one of the sample conditions in %s can be loaded per relax data pipe." % sample_conds) 357 358 # The diffusion tensor. 359 diffusion_tensor.bmrb_read(star) 360 361 # Generate the molecule and residue containers from the entity records. 362 mol_res_spin.bmrb_read(star) 363 364 # Read the relaxation data saveframes. 365 relax_data.bmrb_read(star, sample_conditions=sample_conditions) 366 367 # Read the model-free data saveframes. 368 self._sf_model_free_read(star, sample_conditions=sample_conditions) 369 370 # Read the CSA data saveframes. 371 self._sf_csa_read(star)
372 373
374 - def bmrb_write(self, file_path, version=None):
375 """Write the model-free results to a BMRB NMR-STAR v3.1 formatted file. 376 377 @param file_path: The full file path. 378 @type file_path: str 379 @keyword version: The BMRB NMR-STAR dictionary format to output to. 380 @type version: str 381 """ 382 383 # Alias the current data pipe. 384 cdp = pipes.get_pipe() 385 386 # Initialise the NMR-STAR data object. 387 star = bmrblib.create_nmr_star('relax_model_free_results', file_path, version) 388 389 # Global minimisation stats. 390 global_chi2 = None 391 if hasattr(cdp, 'chi2'): 392 global_chi2 = cdp.chi2 393 394 # Rex frq. 395 rex_frq = cdp.frq[cdp.ri_ids[0]] 396 397 # Initialise the spin specific data lists. 398 mol_name_list = [] 399 res_num_list = [] 400 res_name_list = [] 401 atom_name_list = [] 402 403 csa_list = [] 404 r_list = [] 405 isotope_list = [] 406 element_list = [] 407 408 local_tm_list = [] 409 s2_list = [] 410 s2f_list = [] 411 s2s_list = [] 412 te_list = [] 413 tf_list = [] 414 ts_list = [] 415 rex_list = [] 416 417 local_tm_err_list = [] 418 s2_err_list = [] 419 s2f_err_list = [] 420 s2s_err_list = [] 421 te_err_list = [] 422 tf_err_list = [] 423 ts_err_list = [] 424 rex_err_list = [] 425 426 chi2_list = [] 427 model_list = [] 428 429 # Store the spin specific data in lists for later use. 430 for spin, mol_name, res_num, res_name, spin_id in spin_loop(full_info=True, return_id=True): 431 # Check the data for None (not allowed in BMRB!). 432 if res_num == None: 433 raise RelaxError("For the BMRB, the residue of spin '%s' must be numbered." % spin_id) 434 if res_name == None: 435 raise RelaxError("For the BMRB, the residue of spin '%s' must be named." % spin_id) 436 if spin.name == None: 437 raise RelaxError("For the BMRB, the spin '%s' must be named." % spin_id) 438 if spin.heteronuc_type == None: 439 raise RelaxError("For the BMRB, the spin isotope type of '%s' must be specified." % spin_id) 440 if not hasattr(spin, 'element') or spin.element == None: 441 raise RelaxError("For the BMRB, the spin element type of '%s' must be specified. Please use the spin user function for setting the element type." % spin_id) 442 443 # The molecule/residue/spin info. 444 mol_name_list.append(mol_name) 445 res_num_list.append(res_num) 446 res_name_list.append(res_name) 447 atom_name_list.append(spin.name) 448 449 # CSA values. 450 if hasattr(spin, 'csa'): 451 csa_list.append(spin.csa * 1e6) # In ppm. 452 else: 453 csa_list.append(None) 454 455 # Bond lengths. 456 if hasattr(spin, 'csa'): 457 r_list.append(spin.r) 458 else: 459 r_list.append(None) 460 461 # The heteronucleus type. 462 if hasattr(spin, 'csa'): 463 isotope_list.append(int(string.strip(spin.heteronuc_type, string.ascii_letters))) 464 else: 465 isotope_list.append(None) 466 467 # The element. 468 if hasattr(spin, 'element'): 469 element_list.append(spin.element) 470 else: 471 element_list.append(None) 472 473 # Diffusion tensor. 474 local_tm_list.append(spin.local_tm) 475 if hasattr(spin, 'local_tm_err'): 476 local_tm_err_list.append(spin.local_tm_err) 477 else: 478 local_tm_err_list.append(None) 479 480 # Model-free parameter values. 481 s2_list.append(spin.s2) 482 s2f_list.append(spin.s2f) 483 s2s_list.append(spin.s2s) 484 te_list.append(spin.te) 485 tf_list.append(spin.tf) 486 ts_list.append(spin.ts) 487 if spin.rex == None: 488 rex_list.append(None) 489 else: 490 rex_list.append(spin.rex / (2.0*pi*rex_frq**2)) 491 492 # Model-free parameter errors. 493 params = ['s2', 's2f', 's2s', 'te', 'tf', 'ts', 'rex'] 494 for param in params: 495 # The error list. 496 err_list = locals()[param+'_err_list'] 497 498 # Append the error. 499 if hasattr(spin, param+'_err'): 500 # The value. 501 val = getattr(spin, param+'_err') 502 503 # Scaling. 504 if param == 'rex' and val != None: 505 val = val / (2.0*pi*rex_frq**2) 506 507 # Append. 508 err_list.append(val) 509 510 # Or None. 511 else: 512 err_list.append(None) 513 514 515 # Opt stats. 516 chi2_list.append(spin.chi2) 517 518 # Model-free model. 519 model_list.append(self._to_bmrb_model(spin.model)) 520 521 # Convert the molecule names into the entity IDs. 522 entity_ids = zeros(len(mol_name_list), int32) 523 mol_names = get_molecule_names() 524 for i in range(len(mol_name_list)): 525 for j in range(len(mol_names)): 526 if mol_name_list[i] == mol_names[j]: 527 entity_ids[i] = j+1 528 529 530 # Create Supergroup 2 : The citations. 531 ###################################### 532 533 # Generate the citations saveframe. 534 exp_info.bmrb_write_citations(star) 535 536 537 # Create Supergroup 3 : The molecular assembly saveframes. 538 ########################################################## 539 540 # Generate the entity saveframe. 541 mol_res_spin.bmrb_write_entity(star) 542 543 544 # Create Supergroup 4: The experimental descriptions saveframes. 545 ################################################################# 546 547 # Generate the method saveframes. 548 exp_info.bmrb_write_methods(star) 549 550 # Generate the software saveframe. 551 software_ids, software_labels = exp_info.bmrb_write_software(star) 552 553 554 # Create Supergroup 5 : The NMR parameters saveframes. 555 ###################################################### 556 557 # Generate the CSA saveframe. 558 star.chem_shift_anisotropy.add(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, csa=csa_list) 559 560 561 # Create Supergroup 6 : The kinetic data saveframes. 562 #################################################### 563 564 # Generate the relaxation data saveframes. 565 relax_data.bmrb_write(star) 566 567 568 # Create Supergroup 7 : The thermodynamics saveframes. 569 ###################################################### 570 571 # Get the relax software id. 572 for i in range(len(software_ids)): 573 if software_labels[i] == 'relax': 574 software_id = software_ids[i] 575 576 # Generate the model-free data saveframe. 577 star.model_free.add(global_chi2=global_chi2, software_ids=[software_id], software_labels=['relax'], 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, bond_length=r_list, local_tc=local_tm_list, s2=s2_list, s2f=s2f_list, s2s=s2s_list, te=te_list, tf=tf_list, ts=ts_list, rex=rex_list, local_tc_err=local_tm_err_list, s2_err=s2_err_list, s2f_err=s2f_err_list, s2s_err=s2s_err_list, te_err=te_err_list, tf_err=tf_err_list, ts_err=ts_err_list, rex_err=rex_err_list, rex_frq=rex_frq, chi2=chi2_list, model_fit=model_list) 578 579 580 # Create Supergroup 8 : The structure determination saveframes. 581 ############################################################### 582 583 # Generate the diffusion tensor saveframes. 584 diffusion_tensor.bmrb_write(star) 585 586 587 # Write the contents to the STAR formatted file. 588 star.write()
589