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 # Skip deselected spins. 432 if not spin.select: 433 continue 434 435 # Check the data for None (not allowed in BMRB!). 436 if res_num == None: 437 raise RelaxError("For the BMRB, the residue of spin '%s' must be numbered." % spin_id) 438 if res_name == None: 439 raise RelaxError("For the BMRB, the residue of spin '%s' must be named." % spin_id) 440 if spin.name == None: 441 raise RelaxError("For the BMRB, the spin '%s' must be named." % spin_id) 442 if spin.heteronuc_type == None: 443 raise RelaxError("For the BMRB, the spin isotope type of '%s' must be specified." % spin_id) 444 if not hasattr(spin, 'element') or spin.element == None: 445 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) 446 447 # The molecule/residue/spin info. 448 mol_name_list.append(mol_name) 449 res_num_list.append(res_num) 450 res_name_list.append(res_name) 451 atom_name_list.append(spin.name) 452 453 # Values. 454 csa_list.append(spin.csa * 1e6) # In ppm. 455 r_list.append(spin.r) 456 isotope_list.append(int(string.strip(spin.heteronuc_type, string.ascii_letters))) 457 element_list.append(spin.element) 458 459 # Diffusion tensor. 460 local_tm_list.append(spin.local_tm) 461 if hasattr(spin, 'local_tm_err'): 462 local_tm_err_list.append(spin.local_tm_err) 463 else: 464 local_tm_err_list.append(None) 465 466 # Model-free parameter values. 467 s2_list.append(spin.s2) 468 s2f_list.append(spin.s2f) 469 s2s_list.append(spin.s2s) 470 te_list.append(spin.te) 471 tf_list.append(spin.tf) 472 ts_list.append(spin.ts) 473 if spin.rex == None: 474 rex_list.append(None) 475 else: 476 rex_list.append(spin.rex / (2.0*pi*rex_frq**2)) 477 478 # Model-free parameter errors. 479 params = ['s2', 's2f', 's2s', 'te', 'tf', 'ts', 'rex'] 480 for param in params: 481 # The error list. 482 err_list = locals()[param+'_err_list'] 483 484 # Append the error. 485 if hasattr(spin, param+'_err'): 486 # The value. 487 val = getattr(spin, param+'_err') 488 489 # Scaling. 490 if param == 'rex' and val != None: 491 val = val / (2.0*pi*rex_frq**2) 492 493 # Append. 494 err_list.append(val) 495 496 # Or None. 497 else: 498 err_list.append(None) 499 500 501 # Opt stats. 502 chi2_list.append(spin.chi2) 503 504 # Model-free model. 505 model_list.append(self._to_bmrb_model(spin.model)) 506 507 # Convert the molecule names into the entity IDs. 508 entity_ids = zeros(len(mol_name_list), int32) 509 mol_names = get_molecule_names() 510 for i in range(len(mol_name_list)): 511 for j in range(len(mol_names)): 512 if mol_name_list[i] == mol_names[j]: 513 entity_ids[i] = j+1 514 515 516 # Create Supergroup 2 : The citations. 517 ###################################### 518 519 # Generate the citations saveframe. 520 exp_info.bmrb_write_citations(star) 521 522 523 # Create Supergroup 3 : The molecular assembly saveframes. 524 ########################################################## 525 526 # Generate the entity saveframe. 527 mol_res_spin.bmrb_write_entity(star) 528 529 530 # Create Supergroup 4: The experimental descriptions saveframes. 531 ################################################################# 532 533 # Generate the method saveframes. 534 exp_info.bmrb_write_methods(star) 535 536 # Generate the software saveframe. 537 software_ids, software_labels = exp_info.bmrb_write_software(star) 538 539 540 # Create Supergroup 5 : The NMR parameters saveframes. 541 ###################################################### 542 543 # Generate the CSA saveframe. 544 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) 545 546 547 # Create Supergroup 6 : The kinetic data saveframes. 548 #################################################### 549 550 # Generate the relaxation data saveframes. 551 relax_data.bmrb_write(star) 552 553 554 # Create Supergroup 7 : The thermodynamics saveframes. 555 ###################################################### 556 557 # Get the relax software id. 558 for i in range(len(software_ids)): 559 if software_labels[i] == 'relax': 560 software_id = software_ids[i] 561 562 # Generate the model-free data saveframe. 563 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) 564 565 566 # Create Supergroup 8 : The structure determination saveframes. 567 ############################################################### 568 569 # Generate the diffusion tensor saveframes. 570 diffusion_tensor.bmrb_write(star) 571 572 573 # Write the contents to the STAR formatted file. 574 star.write()
575