Package pipe_control :: Module mol_res_spin
[hide private]
[frames] | no frames]

Source Code for Module pipe_control.mol_res_spin

   1  ############################################################################### 
   2  #                                                                             # 
   3  # Copyright (C) 2003-2013 Edward d'Auvergne                                   # 
   4  #                                                                             # 
   5  # This file is part of the program relax (http://www.nmr-relax.com).          # 
   6  #                                                                             # 
   7  # This program 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 3 of the License, or           # 
  10  # (at your option) any later version.                                         # 
  11  #                                                                             # 
  12  # This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.       # 
  19  #                                                                             # 
  20  ############################################################################### 
  21   
  22  # Module docstring. 
  23  """Module for the manipulation of the molecule-residue-spin data structures in the relax data store. 
  24   
  25  The functionality of this module is diverse: 
  26      - Documentation for the spin identification string. 
  27      - Functions for parsing or generating spin identification strings. 
  28      - The mol-res-spin selection object (derived from the Selection class). 
  29      - Generator functions for looping over molecules, residues, or spins. 
  30      - Functions for returning MoleculeContainer, ResidueContainer, and SpinContainer objects or information about these. 
  31      - Functions for copying, creating, deleting, displaying, naming, and numbering MoleculeContainer, ResidueContainer, and SpinContainer objects in the relax data store. 
  32      - Functions for counting spins or testing their existence. 
  33  """ 
  34   
  35  # Python module imports. 
  36  from numpy import array, float64 
  37  import sys 
  38  from warnings import warn 
  39   
  40  # relax module imports. 
  41  from lib.check_types import is_unicode 
  42  from lib.errors import RelaxError, RelaxNoSequenceError, RelaxNoSpinError, RelaxMultiMolIDError, RelaxMultiResIDError, RelaxMultiSpinIDError, RelaxResSelectDisallowError, RelaxSpinSelectDisallowError 
  43  from lib.selection import Selection, parse_token, tokenise 
  44  from lib.warnings import RelaxWarning 
  45  from pipe_control import exp_info, pipes 
  46  from status import Status; status = Status() 
  47  from user_functions.objects import Desc_container 
  48   
  49   
  50  ALLOWED_MOL_TYPES = ['protein', 
  51                       'DNA', 
  52                       'RNA', 
  53                       'organic molecule', 
  54                       'inorganic molecule' 
  55  ] 
  56  """The list of allowable molecule types.""" 
  57   
  58  id_string_doc = Desc_container("Spin ID string documentation") 
  59  id_string_doc.add_paragraph("The identification string is composed of three components: the molecule ID token beginning with the '#' character, the residue ID token beginning with the ':' character, and the atom or spin system ID token beginning with the '@' character.  Each token can be composed of multiple elements - one per spin - separated by the ',' character and each individual element can either be a number (which must be an integer, in string format), a name, or a range of numbers separated by the '-' character.  Negative numbers are supported.  The full ID string specification is '#<mol_name> :<res_id>[, <res_id>[, <res_id>, ...]] @<atom_id>[, <atom_id>[, <atom_id>, ...]]', where the token elements are '<mol_name>', the name of the molecule, '<res_id>', the residue identifier which can be a number, name, or range of numbers, '<atom_id>', the atom or spin system identifier which can be a number, name, or range of numbers.") 
  60  id_string_doc.add_paragraph("If one of the tokens is left out then all elements will be assumed to match.  For example if the string does not contain the '#' character then all molecules will match the string.  If only the molecule ID component is specified, then all spins of the molecule will match.") 
  61  id_string_doc.add_paragraph("Regular expression can be used to select spins.  For example the string '@H*' will select the protons 'H', 'H2', 'H98'.") 
  62   
  63   
64 -def are_spins_named(spin_id=None):
65 """Determine if any spins have been named. 66 67 @keyword spin_id: The spin ID string. 68 @type spin_id: None or str 69 @return: True if a spin has been named or False if no spins have been named. 70 @rtype: bool 71 """ 72 73 # Loop over the spins. 74 for spin in spin_loop(spin_id): 75 # The spin is named. 76 if spin.name != None: 77 return True 78 79 # No spins have been named. 80 return False
81 82
83 -def bmrb_read(star):
84 """Generate the molecule and residue spin containers from the entity saveframe records. 85 86 @param star: The NMR-STAR dictionary object. 87 @type star: NMR_STAR instance 88 """ 89 90 # Get the entities. 91 for data in star.entity.loop(): 92 # Remove nasty characters from the molecule name. 93 mol_name = data['mol_name'] 94 if mol_name: 95 # Round brackets. 96 mol_name = mol_name.replace('(', '') 97 mol_name = mol_name.replace(')', '') 98 99 # Square brackets. 100 mol_name = mol_name.replace('[', '') 101 mol_name = mol_name.replace(']', '') 102 103 # Commas. 104 mol_name = mol_name.replace(',', ' ') 105 106 # The molecule type. 107 mol_type = data['mol_type'] 108 polymer_type = data['polymer_type'] 109 110 # Translate from the BMRB notation to relax'. 111 if mol_type == 'polymer': 112 map = { 113 'DNA/RNA hybrid': 'DNA', 114 'polydeoxyribonucleotide': 'DNA', 115 'polypeptide(D)': 'protein', 116 'polypeptide(L)': 'protein', 117 'polyribonucleotide': 'RNA', 118 'polysaccharide(D)': 'organic molecule', 119 'polysaccharide(L)': 'organic molecule' 120 } 121 mol_type = map[polymer_type] 122 123 # Create the molecule. 124 create_molecule(mol_name=mol_name, mol_type=mol_type) 125 126 # The thiol state. 127 exp_info.thiol_state(data['thiol_state']) 128 129 # Add the residues. 130 for i in range(len(data['res_nums'])): 131 create_residue(data['res_nums'][i], data['res_names'][i], mol_name=mol_name)
132 133
134 -def bmrb_write_entity(star, version=None):
135 """Generate the entity saveframe records for the NMR-STAR dictionary object. 136 137 @param star: The NMR-STAR dictionary object. 138 @type star: NMR_STAR instance 139 @keyword version: The BMRB NMR-STAR dictionary format to output to. 140 @type version: str 141 """ 142 143 # Loop over the molecules. 144 for mol in molecule_loop(): 145 # Test that the molecule has a name! 146 if not mol.name: 147 raise RelaxError("All molecules must be named.") 148 149 # Test that the molecule has a type! 150 if not hasattr(mol, 'type') or not mol.type: 151 raise RelaxError("The molecule type for the '%s' molecule must be specified, please use the appropriate molecule user function to set this." % mol.name) 152 153 # Test that the molecule thiol state has been set. 154 if not hasattr(cdp, 'exp_info') or not hasattr(cdp.exp_info, 'thiol_state'): 155 raise RelaxError("The thiol state of the molecule '%s' must be specified, please use the appropriate BMRB user function to set this." % mol.name) 156 157 # Get the residue names and numbers. 158 res_names = get_residue_names("#" + mol.name) 159 res_nums = get_residue_nums("#" + mol.name) 160 161 # Get the one letter codes. 162 polymer_seq_code = one_letter_code(res_names) 163 164 # Find the molecule type. 165 if mol.type in ['organic molecule', 'other']: 166 mol_type = 'non-polymer' 167 else: 168 mol_type = 'polymer' 169 170 # Translate the names. 171 polymer_type = mol.type 172 if polymer_type == 'protein': 173 polymer_type = 'polypeptide(L)' 174 if polymer_type == 'DNA': 175 polymer_type = 'polydeoxyribonucleotide' 176 if polymer_type == 'RNA': 177 polymer_type = 'polyribonucleotide' 178 if polymer_type == 'inorganic molecule': 179 polymer_type = 'other' 180 181 # Add the entity. 182 star.entity.add(mol_name=mol.name, mol_type=mol_type, polymer_type=polymer_type, polymer_seq_code=polymer_seq_code, thiol_state=cdp.exp_info.thiol_state, res_nums=res_nums, res_names=res_names)
183 184
185 -def check_mol_res_spin_data():
186 """Check for the presence of molecule, residue, and spin data. 187 188 @raises RelaxNoSequenceError: If no data is present. 189 """ 190 191 # Check that the spectrum ID structure exists. 192 if not exists_mol_res_spin_data(): 193 raise RelaxNoSequenceError
194 195
196 -def copy_molecule(pipe_from=None, mol_from=None, pipe_to=None, mol_to=None):
197 """Copy the contents of a molecule container to a new molecule. 198 199 For copying to be successful, the mol_from identification string must match an existent molecule. 200 201 202 @param pipe_from: The data pipe to copy the molecule data from. This defaults to the current data pipe. 203 @type pipe_from: str 204 @param mol_from: The molecule identification string for the structure to copy the data from. 205 @type mol_from: str 206 @param pipe_to: The data pipe to copy the molecule data to. This defaults to the current data pipe. 207 @type pipe_to: str 208 @param mol_to: The molecule identification string for the structure to copy the data to. 209 @type mol_to: str 210 """ 211 212 # Acquire the spin lock (data modifying function), and make sure it is finally released. 213 status.spin_lock.acquire(sys._getframe().f_code.co_name) 214 try: 215 # The current data pipe. 216 if pipe_from == None: 217 pipe_from = pipes.cdp_name() 218 if pipe_to == None: 219 pipe_to = pipes.cdp_name() 220 221 # The second pipe does not exist. 222 pipes.test(pipe_to) 223 224 # Split up the selection string. 225 mol_from_token, res_from_token, spin_from_token = tokenise(mol_from) 226 mol_to_token, res_to_token, spin_to_token = tokenise(mol_to) 227 228 # Disallow spin selections. 229 if spin_from_token != None or spin_to_token != None: 230 raise RelaxSpinSelectDisallowError 231 232 # Disallow residue selections. 233 if res_from_token != None or res_to_token != None: 234 raise RelaxResSelectDisallowError 235 236 # Parse the molecule token for renaming. 237 mol_name_to = return_single_molecule_info(mol_to_token) 238 239 # Test if the molecule name already exists. 240 mol_to_cont = return_molecule(mol_to, pipe_to) 241 if mol_to_cont and not mol_to_cont.is_empty(): 242 raise RelaxError("The molecule " + repr(mol_to) + " already exists in the " + repr(pipe_to) + " data pipe.") 243 244 # Get the single molecule data container. 245 mol_from_cont = return_molecule(mol_from, pipe_from) 246 247 # No molecule to copy data from. 248 if mol_from_cont == None: 249 raise RelaxError("The molecule " + repr(mol_from) + " does not exist in the " + repr(pipe_from) + " data pipe.") 250 251 # Get the target pipe. 252 pipe = pipes.get_pipe(pipe_to) 253 254 # Copy the data. 255 if pipe.mol[0].name == None and len(pipe.mol) == 1: 256 pipe.mol[0] = mol_from_cont.__clone__() 257 else: 258 pipe.mol.append(mol_from_cont.__clone__()) 259 260 # Change the new molecule name. 261 if mol_name_to != None: 262 pipe.mol[-1].name = mol_name_to 263 264 # Update the private metadata. 265 metadata_update(pipe=pipe_to) 266 267 # Release the lock. 268 finally: 269 status.spin_lock.release(sys._getframe().f_code.co_name)
270 271
272 -def copy_residue(pipe_from=None, res_from=None, pipe_to=None, res_to=None):
273 """Copy the contents of the residue structure from one residue to a new residue. 274 275 For copying to be successful, the res_from identification string must match an existent residue. The new residue number must be unique. 276 277 @param pipe_from: The data pipe to copy the residue from. This defaults to the current data pipe. 278 @type pipe_from: str 279 @param res_from: The residue identification string for the structure to copy the data from. 280 @type res_from: str 281 @param pipe_to: The data pipe to copy the residue to. This defaults to the current data pipe. 282 @type pipe_to: str 283 @param res_to: The residue identification string for the structure to copy the data to. 284 @type res_to: str 285 """ 286 287 # Acquire the spin lock (data modifying function), and make sure it is finally released. 288 status.spin_lock.acquire(sys._getframe().f_code.co_name) 289 try: 290 # The current data pipe. 291 if pipe_from == None: 292 pipe_from = pipes.cdp_name() 293 if pipe_to == None: 294 pipe_to = pipes.cdp_name() 295 296 # The second pipe does not exist. 297 pipes.test(pipe_to) 298 299 # Get the target pipe. 300 pipe = pipes.get_pipe(pipe_to) 301 302 # Split up the selection string. 303 mol_from_token, res_from_token, spin_from_token = tokenise(res_from) 304 mol_to_token, res_to_token, spin_to_token = tokenise(res_to) 305 306 # Disallow spin selections. 307 if spin_from_token != None or spin_to_token != None: 308 raise RelaxSpinSelectDisallowError 309 310 # Parse the residue token for renaming and renumbering. 311 res_num_to, res_name_to = return_single_residue_info(res_to_token) 312 313 # Test if the residue number already exists. 314 res_to_cont = return_residue(res_to, pipe_to) 315 if res_to_cont and not res_to_cont.is_empty(): 316 raise RelaxError("The residue " + repr(res_to) + " already exists in the " + repr(pipe_to) + " data pipe.") 317 318 # Get the single residue data container. 319 res_from_cont = return_residue(res_from, pipe_from) 320 321 # No residue to copy data from. 322 if res_from_cont == None: 323 raise RelaxError("The residue " + repr(res_from) + " does not exist in the " + repr(pipe_from) + " data pipe.") 324 325 # Get the single molecule data container to copy the residue to (default to the first molecule). 326 mol_to_container = return_molecule(res_to, pipe_to) 327 if mol_to_container == None: 328 mol_to_container = pipe.mol[0] 329 330 # Copy the data. 331 if mol_to_container.res[0].num == None and mol_to_container.res[0].name == None and len(mol_to_container.res) == 1: 332 mol_to_container.res[0] = res_from_cont.__clone__() 333 else: 334 mol_to_container.res.append(res_from_cont.__clone__()) 335 336 # Change the new residue number and name. 337 if res_num_to != None: 338 mol_to_container.res[-1].num = res_num_to 339 if res_name_to != None: 340 mol_to_container.res[-1].name = res_name_to 341 342 # Update the private metadata. 343 metadata_update(pipe=pipe_to) 344 345 # Release the lock. 346 finally: 347 status.spin_lock.release(sys._getframe().f_code.co_name)
348 349
350 -def copy_spin(pipe_from=None, spin_from=None, pipe_to=None, spin_to=None):
351 """Copy the contents of the spin structure from one spin to a new spin. 352 353 For copying to be successful, the spin_from identification string must match an existent spin. The new spin number must be unique. 354 355 356 @param pipe_from: The data pipe to copy the spin from. This defaults to the current data pipe. 357 @type pipe_from: str 358 @param spin_from: The spin identification string for the structure to copy the data from. 359 @type spin_from: str 360 @param pipe_to: The data pipe to copy the spin to. This defaults to the current data pipe. 361 @type pipe_to: str 362 @param spin_to: The spin identification string for the structure to copy the data to. 363 @type spin_to: str 364 """ 365 366 # Acquire the spin lock (data modifying function), and make sure it is finally released. 367 status.spin_lock.acquire(sys._getframe().f_code.co_name) 368 try: 369 # The current data pipe. 370 if pipe_from == None: 371 pipe_from = pipes.cdp_name() 372 if pipe_to == None: 373 pipe_to = pipes.cdp_name() 374 375 # The second pipe does not exist. 376 pipes.test(pipe_to) 377 378 # Get the target pipe. 379 pipe = pipes.get_pipe(pipe_to) 380 381 # Split up the selection string. 382 mol_to_token, res_to_token, spin_to_token = tokenise(spin_to) 383 384 # Test if the spin number already exists. 385 if spin_to_token: 386 spin_to_cont = return_spin(spin_to, pipe_to) 387 if spin_to_cont and not spin_to_cont.is_empty(): 388 raise RelaxError("The spin " + repr(spin_to) + " already exists in the " + repr(pipe_from) + " data pipe.") 389 390 # No residue to copy data from. 391 if not return_residue(spin_from, pipe_from): 392 raise RelaxError("The residue in " + repr(spin_from) + " does not exist in the " + repr(pipe_from) + " data pipe.") 393 394 # No spin to copy data from. 395 spin_from_cont = return_spin(spin_from, pipe_from) 396 if spin_from_cont == None: 397 raise RelaxError("The spin " + repr(spin_from) + " does not exist in the " + repr(pipe_from) + " data pipe.") 398 399 # Get the single residue data container to copy the spin to (default to the first molecule, first residue). 400 res_to_cont = return_residue(spin_to, pipe_to) 401 if res_to_cont == None and spin_to: 402 # No residue to copy data to. 403 raise RelaxError("The residue in " + repr(spin_to) + " does not exist in the " + repr(pipe_from) + " data pipe.") 404 if res_to_cont == None: 405 res_to_cont = pipe.mol[0].res[0] 406 407 # Copy the data. 408 if len(res_to_cont.spin) == 1 and res_to_cont.spin[0].is_empty(): 409 res_to_cont.spin[0] = spin_from_cont.__clone__() 410 else: 411 res_to_cont.spin.append(spin_from_cont.__clone__()) 412 413 # Parse the spin token for renaming and renumbering. 414 spin_num_to, spin_name_to = return_single_spin_info(spin_to_token) 415 416 # Change the new spin number and name. 417 if spin_num_to != None: 418 res_to_cont.spin[-1].num = spin_num_to 419 if spin_name_to != None: 420 res_to_cont.spin[-1].name = spin_name_to 421 422 # Update the private metadata. 423 metadata_update(pipe=pipe_to) 424 425 # Release the lock. 426 finally: 427 status.spin_lock.release(sys._getframe().f_code.co_name)
428 429
430 -def count_max_spins_per_residue(pipe=None, spin_id=None, skip_desel=True):
431 """Determine the maximum number of spins present per residue. 432 433 @keyword pipe: The data pipe containing the spin. Defaults to the current data pipe. 434 @type pipe: str 435 @param spin_id: The molecule, residue, and spin identifier string. 436 @type spin_id: str 437 @keyword skip_desel: A flag which if true will cause deselected spins to be skipped in the count. 438 @type skip_desel: bool 439 @return: The number of non-empty spins. 440 @rtype: int 441 """ 442 443 # The data pipe. 444 if pipe == None: 445 pipe = pipes.cdp_name() 446 447 # Test the data pipe. 448 pipes.test(pipe) 449 450 # No data, hence no spins. 451 if not exists_mol_res_spin_data(pipe=pipe): 452 return 0 453 454 # Init. 455 max_num = 0 456 457 # Get the data pipe. 458 dp = pipes.get_pipe(pipe) 459 460 # Parse the selection string. 461 select_obj = Selection(spin_id) 462 463 # Loop over the molecules. 464 for mol in dp.mol: 465 # Loop over the residues. 466 for res in mol.res: 467 # Initialise the counter. 468 spin_num = 0 469 470 # Loop over the spins. 471 for spin in res.spin: 472 # Skip the spin if there is no match to the selection. 473 if not select_obj.contains_spin(spin_num=spin.num, spin_name=spin.name, res_num=res.num, res_name=res.name, mol=mol.name): 474 continue 475 476 # Skip deselected spins. 477 if skip_desel and not spin.select: 478 continue 479 480 # Increment the spin number. 481 spin_num = spin_num + 1 482 483 # The maximum number. 484 max_num = max(max_num, spin_num) 485 486 # Return the maximum number of spins. 487 return max_num
488 489
490 -def count_molecules(selection=None, pipe=None):
491 """Count the number of molecules for which there is data. 492 493 @keyword selection: The selection string. 494 @type selection: str 495 @keyword pipe: The data pipe containing the spin. Defaults to the current data pipe. 496 @type pipe: str 497 @return: The number of non-empty molecules. 498 @rtype: int 499 """ 500 501 # The data pipe. 502 if pipe == None: 503 pipe = pipes.cdp_name() 504 505 # Test the data pipe. 506 pipes.test(pipe) 507 508 # No data, hence no molecules. 509 if not exists_mol_res_spin_data(pipe=pipe): 510 return 0 511 512 # Init. 513 mol_num = 0 514 515 # Spin loop. 516 for mol in molecule_loop(selection, pipe=pipe): 517 mol_num = mol_num + 1 518 519 # Return the number of molecules. 520 return mol_num
521 522
523 -def count_residues(selection=None, pipe=None):
524 """Count the number of residues for which there is data. 525 526 @keyword selection: The selection string. 527 @type selection: str 528 @keyword pipe: The data pipe containing the spin. Defaults to the current data pipe. 529 @type pipe: str 530 @return: The number of non-empty residues. 531 @rtype: int 532 """ 533 534 # The data pipe. 535 if pipe == None: 536 pipe = pipes.cdp_name() 537 538 # Test the data pipe. 539 pipes.test(pipe) 540 541 # No data, hence no residues. 542 if not exists_mol_res_spin_data(pipe=pipe): 543 return 0 544 545 # Init. 546 res_num = 0 547 548 # Spin loop. 549 for res in residue_loop(selection, pipe=pipe): 550 res_num = res_num + 1 551 552 # Return the number of residues. 553 return res_num
554 555
556 -def count_spins(selection=None, pipe=None, skip_desel=True):
557 """Function for counting the number of spins for which there is data. 558 559 @keyword selection: The selection string. 560 @type selection: str 561 @keyword pipe: The data pipe containing the spin. Defaults to the current data pipe. 562 @type pipe: str 563 @keyword skip_desel: A flag which if true will cause deselected spins to be skipped in the count. 564 @type skip_desel: bool 565 @return: The number of non-empty spins. 566 @rtype: int 567 """ 568 569 # The data pipe. 570 if pipe == None: 571 pipe = pipes.cdp_name() 572 573 # Test the data pipe. 574 pipes.test(pipe) 575 576 # No data, hence no spins. 577 if not exists_mol_res_spin_data(pipe=pipe): 578 return 0 579 580 # Init. 581 spin_num = 0 582 583 # Spin loop. 584 for spin in spin_loop(selection, pipe=pipe): 585 # Skip deselected spins. 586 if skip_desel and not spin.select: 587 continue 588 589 spin_num = spin_num + 1 590 591 # Return the number of spins. 592 return spin_num
593 594
595 -def create_molecule(mol_name=None, mol_type=None, pipe=None):
596 """Add a molecule into the relax data store. 597 598 @keyword mol_name: The name of the molecule. 599 @type mol_name: str 600 @keyword pipe: The data pipe to add the molecule to. Defaults to the current data pipe. 601 @type pipe: str or None 602 @keyword mol_type: The type of molecule. 603 @type mol_type: str 604 @return: The newly created molecule. 605 @rtype: MoleculeContainer instance 606 """ 607 608 # The data pipe. 609 if pipe == None: 610 pipe = pipes.cdp_name() 611 612 # Test the data pipe. 613 pipes.test(pipe) 614 615 # Get the data pipe. 616 dp = pipes.get_pipe(pipe) 617 618 # Acquire the spin lock (data modifying function), and make sure it is finally released. 619 status.spin_lock.acquire(sys._getframe().f_code.co_name) 620 try: 621 # Test the molecule type. 622 if mol_type and mol_type not in ALLOWED_MOL_TYPES: 623 raise RelaxError("The molecule type '%s' must be one of %s" % (mol_type, ALLOWED_MOL_TYPES)) 624 625 # Test if the molecule name already exists. 626 for i in range(len(dp.mol)): 627 if dp.mol[i].name == mol_name: 628 raise RelaxError("The molecule '" + repr(mol_name) + "' already exists in the relax data store.") 629 630 # Append the molecule. 631 dp.mol.add_item(mol_name=mol_name, mol_type=mol_type) 632 633 # Alias the molecule. 634 mol = dp.mol[-1] 635 636 # Update the private metadata. 637 if len(dp.mol) == 2: 638 metadata_cleanup(pipe=pipe) 639 else: 640 metadata_cleanup(mol_index=len(dp.mol)-1, pipe=pipe) 641 metadata_update(mol_index=len(dp.mol)-1, pipe=pipe) 642 643 # Release the lock. 644 finally: 645 status.spin_lock.release(sys._getframe().f_code.co_name) 646 647 # Return the molecule. 648 return mol
649 650
651 -def create_residue(res_num=None, res_name=None, mol_name=None, pipe=None):
652 """Add a residue into the relax data store (and molecule if necessary). 653 654 @keyword res_num: The number of the new residue. 655 @type res_num: int 656 @keyword res_name: The name of the new residue. 657 @type res_name: str 658 @keyword mol_name: The name of the molecule to add the residue to. 659 @type mol_name: str 660 @keyword pipe: The data pipe to add the residue to. Defaults to the current data pipe. 661 @type pipe: str or None 662 @return: The newly created residue. 663 @rtype: ResidueContainer instance 664 """ 665 666 # The data pipe. 667 if pipe == None: 668 pipe = pipes.cdp_name() 669 670 # Test the data pipe. 671 pipes.test(pipe) 672 673 # Acquire the spin lock (data modifying function), and make sure it is finally released. 674 status.spin_lock.acquire(sys._getframe().f_code.co_name) 675 try: 676 # Create the molecule if it does not exist. 677 mol_cont = return_molecule(generate_spin_id(pipe_name=pipe, mol_name=mol_name), pipe=pipe) 678 if mol_cont == None: 679 mol_cont = create_molecule(mol_name=mol_name, pipe=pipe) 680 681 # Add the residue. 682 mol_cont.res.add_item(res_num=res_num, res_name=res_name) 683 684 # Alias the residue. 685 res = mol_cont.res[-1] 686 687 # Update the private metadata. 688 if len(mol_cont.res) == 2: 689 metadata_cleanup(mol_index=mol_cont._mol_index, pipe=pipe) 690 else: 691 metadata_cleanup(mol_index=mol_cont._mol_index, res_index=len(mol_cont.res)-1, pipe=pipe) 692 metadata_update(mol_index=mol_cont._mol_index, res_index=len(mol_cont.res)-1, pipe=pipe) 693 694 # Release the lock. 695 finally: 696 status.spin_lock.release(sys._getframe().f_code.co_name) 697 698 # Return the residue. 699 return res
700 701
702 -def create_pseudo_spin(spin_name=None, spin_num=None, res_id=None, members=None, averaging=None, pipe=None):
703 """Add a pseudo-atom spin container into the relax data store. 704 705 @param spin_name: The name of the new pseudo-spin. 706 @type spin_name: str 707 @param spin_num: The identification number of the new spin. 708 @type spin_num: int 709 @param res_id: The molecule and residue identification string. 710 @type res_id: str 711 @keyword pipe: The data pipe to add the spin to. Defaults to the current data pipe. 712 @type pipe: str or None 713 """ 714 715 # The data pipe. 716 if pipe == None: 717 pipe = pipes.cdp_name() 718 719 # Test if the current data pipe exists. 720 pipes.test() 721 722 # Get the data pipe. 723 dp = pipes.get_pipe(pipe) 724 725 # Acquire the spin lock (data modifying function), and make sure it is finally released. 726 status.spin_lock.acquire(sys._getframe().f_code.co_name) 727 try: 728 # Split up the selection string. 729 mol_token, res_token, spin_token = tokenise(res_id) 730 731 # Disallow spin selections. 732 if spin_token != None: 733 raise RelaxSpinSelectDisallowError 734 735 # Get the residue container to add the spin to. 736 if res_id: 737 res_to_cont, mol_index, res_index = return_residue(res_id, pipe=pipe, indices=True) 738 if res_to_cont == None: 739 raise RelaxError("The residue in " + repr(res_id) + " does not exist in the current data pipe.") 740 else: 741 res_to_cont = dp.mol[0].res[0] 742 mol_index = 0 743 res_index = 0 744 745 # Check the averaging technique. 746 if averaging not in ['linear']: 747 raise RelaxError("The '%s' averaging technique is unknown." % averaging) 748 749 # Get the spin positions. 750 positions = [] 751 for atom in members: 752 # Get the spin container. 753 spin = return_spin(atom, pipe=pipe) 754 755 # Test that the spin exists. 756 if spin == None: 757 raise RelaxNoSpinError(atom) 758 759 # Test the position. 760 if not hasattr(spin, 'pos') or spin.pos == None: 761 raise RelaxError("Positional information is not available for the atom '%s'." % atom) 762 763 # Alias the position. 764 pos = spin.pos 765 766 # Convert to a list of lists if not already. 767 multi_model = True 768 if type(pos[0]) in [float, float64]: 769 multi_model = False 770 pos = [pos] 771 772 # Store the position. 773 positions.append([]) 774 for i in range(len(pos)): 775 positions[-1].append(pos[i].tolist()) 776 777 # Now add the pseudo-spin name to the spins belonging to it (after the tests). 778 for atom in members: 779 # Get the spin container. 780 spin = return_spin(atom, pipe=pipe) 781 782 # Add the pseudo-spin number and name. 783 if res_id: 784 spin.pseudo_name = res_id + '@' + spin_name 785 else: 786 spin.pseudo_name = '@' + spin_name 787 spin.pseudo_num = spin_num 788 789 # Add the spin. 790 res_to_cont.spin.add_item(spin_num=spin_num, spin_name=spin_name) 791 spin = res_to_cont.spin[-1] 792 spin_index = len(res_to_cont.spin) - 1 793 794 # Set the pseudo-atom spin container attributes. 795 spin.averaging = averaging 796 spin.members = members 797 if averaging == 'linear': 798 # Average pos. 799 ave = linear_ave(positions) 800 801 # Convert to the correct structure. 802 if multi_model: 803 spin.pos = ave 804 else: 805 spin.pos = ave[0] 806 807 # Update the private metadata. 808 metadata_cleanup(mol_index=mol_index, res_index=res_index, pipe=pipe) 809 metadata_update(mol_index=mol_index, res_index=res_index, pipe=pipe) 810 811 # Release the lock. 812 finally: 813 status.spin_lock.release(sys._getframe().f_code.co_name)
814 815
816 -def create_spin(spin_num=None, spin_name=None, res_num=None, res_name=None, mol_name=None, pipe=None):
817 """Add a spin into the relax data store (and molecule and residue if necessary). 818 819 @keyword spin_num: The number of the new spin. 820 @type spin_num: int 821 @keyword spin_name: The name of the new spin. 822 @type spin_name: str 823 @keyword res_num: The number of the residue to add the spin to. 824 @type res_num: int 825 @keyword res_name: The name of the residue to add the spin to. 826 @type res_name: str 827 @keyword mol_name: The name of the molecule to add the spin to. 828 @type mol_name: str 829 @keyword pipe: The data pipe to add the spin to. Defaults to the current data pipe. 830 @type pipe: str or None 831 @return: The newly created spin. 832 @rtype: SpinContainer instance 833 """ 834 835 # The data pipe. 836 if pipe == None: 837 pipe = pipes.cdp_name() 838 839 # Test if the current data pipe exists. 840 pipes.test() 841 842 # Get the data pipe. 843 dp = pipes.get_pipe(pipe) 844 845 # Acquire the spin lock (data modifying function), and make sure it is finally released. 846 status.spin_lock.acquire(sys._getframe().f_code.co_name) 847 try: 848 # Create the molecule if it does not exist. 849 mol_index = index_molecule(mol_name, pipe=pipe) 850 if mol_index == None: 851 create_molecule(mol_name=mol_name, pipe=pipe) 852 mol_index = len(dp.mol) - 1 853 854 # Create the residue if it does not exist. 855 res_index = index_residue(res_num=res_num, res_name=res_name, mol_index=mol_index, pipe=pipe) 856 if res_index == None: 857 create_residue(mol_name=mol_name, res_num=res_num, res_name=res_name, pipe=pipe) 858 res_index = len(dp.mol[mol_index].res) - 1 859 860 # Alias the residue. 861 res_cont = dp.mol[mol_index].res[res_index] 862 863 # Rename the spin, if only a single one exists and it is empty. 864 if len(res_cont.spin) == 1 and res_cont.spin[0].is_empty(): 865 spin_cont = res_cont.spin[0] 866 spin_cont.name = spin_name 867 spin_cont.num = spin_num 868 869 # Otherwise add the spin. 870 else: 871 res_cont.spin.add_item(spin_num=spin_num, spin_name=spin_name) 872 spin_cont = res_cont.spin[-1] 873 874 # The spin index and id. 875 spin_index = len(res_cont.spin) - 1 876 spin_id = generate_spin_id(pipe_cont=dp, mol_name=mol_name, res_num=res_num, res_name=res_name, spin_num=spin_num, spin_name=spin_name) 877 878 # Update the private metadata. 879 if len(res_cont.spin) == 2: 880 metadata_cleanup(mol_index=mol_index, res_index=res_index, pipe=pipe) 881 else: 882 metadata_cleanup(mol_index=mol_index, res_index=res_index, spin_index=spin_index, pipe=pipe) 883 metadata_update(mol_index=mol_index, res_index=res_index, spin_index=spin_index, pipe=pipe) 884 885 # Release the lock. 886 finally: 887 status.spin_lock.release(sys._getframe().f_code.co_name) 888 889 # Return the spin. 890 return spin_cont
891 892
893 -def convert_from_global_index(global_index=None, pipe=None):
894 """Convert the global index into the molecule, residue, and spin indices. 895 896 @param global_index: The global spin index, spanning the molecule and residue containers. 897 @type global_index: int 898 @param pipe: The data pipe containing the spin. Defaults to the current data pipe. 899 @type pipe: str 900 @return: The corresponding molecule, residue, and spin indices. 901 @rtype: tuple of int 902 """ 903 904 # The data pipe. 905 if pipe == None: 906 pipe = pipes.cdp_name() 907 908 # Test the data pipe. 909 pipes.test(pipe) 910 911 # Loop over the spins. 912 spin_num = 0 913 for mol_index, res_index, spin_index in spin_index_loop(pipe=pipe): 914 # Match to the global index. 915 if spin_num == global_index: 916 return mol_index, res_index, spin_index 917 918 # Increment the spin number. 919 spin_num = spin_num + 1
920 921
922 -def delete_molecule(mol_id=None):
923 """Function for deleting molecules from the current data pipe. 924 925 @param mol_id: The molecule identifier string. 926 @type mol_id: str 927 """ 928 929 # Acquire the spin lock (data modifying function), and make sure it is finally released. 930 status.spin_lock.acquire(sys._getframe().f_code.co_name) 931 try: 932 # Split up the selection string. 933 mol_token, res_token, spin_token = tokenise(mol_id) 934 935 # Disallow spin selections. 936 if spin_token != None: 937 raise RelaxSpinSelectDisallowError 938 939 # Disallow residue selections. 940 if res_token != None: 941 raise RelaxResSelectDisallowError 942 943 # Parse the token. 944 molecules = parse_token(mol_token) 945 946 # List of indices to delete. 947 indices = [] 948 949 # Loop over the molecules. 950 for i in range(len(cdp.mol)): 951 # Remove the residue is there is a match. 952 if cdp.mol[i].name in molecules: 953 indices.append(i) 954 955 # Reverse the indices. 956 indices.reverse() 957 958 # First prune the metadata. 959 for index in indices: 960 metadata_prune(mol_index=index) 961 962 # Delete the molecules. 963 for index in indices: 964 cdp.mol.pop(index) 965 966 # Create an empty residue container if no residues remain. 967 if len(cdp.mol) == 0: 968 cdp.mol.add_item() 969 970 # Release the lock. 971 finally: 972 status.spin_lock.release(sys._getframe().f_code.co_name)
973 974
975 -def delete_residue(res_id=None):
976 """Function for deleting residues from the current data pipe. 977 978 @param res_id: The molecule and residue identifier string. 979 @type res_id: str 980 """ 981 982 # Acquire the spin lock (data modifying function), and make sure it is finally released. 983 status.spin_lock.acquire(sys._getframe().f_code.co_name) 984 try: 985 # Split up the selection string. 986 mol_token, res_token, spin_token = tokenise(res_id) 987 988 # Disallow spin selections. 989 if spin_token != None: 990 raise RelaxSpinSelectDisallowError 991 992 # Parse the tokens. 993 residues = parse_token(res_token) 994 995 # Molecule loop. 996 for mol in molecule_loop(res_id): 997 # List of indices to delete. 998 indices = [] 999 1000 # Loop over the residues of the molecule. 1001 for i in range(len(mol.res)): 1002 # Remove the residue is there is a match. 1003 if mol.res[i].num in residues or mol.res[i].name in residues: 1004 indices.append(i) 1005 1006 # Reverse the indices. 1007 indices.reverse() 1008 1009 # First prune the metadata. 1010 for index in indices: 1011 metadata_prune(mol_index=mol._mol_index, res_index=index) 1012 1013 # Delete the residues. 1014 for index in indices: 1015 mol.res.pop(index) 1016 1017 # Create an empty residue container if no residues remain. 1018 if len(mol.res) == 0: 1019 mol.res.add_item() 1020 1021 # Release the lock. 1022 finally: 1023 status.spin_lock.release(sys._getframe().f_code.co_name)
1024 1025
1026 -def delete_spin(spin_id=None):
1027 """Function for deleting spins from the current data pipe. 1028 1029 @param spin_id: The molecule, residue, and spin identifier string. 1030 @type spin_id: str 1031 """ 1032 1033 # Acquire the spin lock (data modifying function), and make sure it is finally released. 1034 status.spin_lock.acquire(sys._getframe().f_code.co_name) 1035 try: 1036 1037 # Split up the selection string. 1038 mol_token, res_token, spin_token = tokenise(spin_id) 1039 1040 # Parse the tokens. 1041 spins = parse_token(spin_token) 1042 1043 # Residue loop. 1044 for res in residue_loop(spin_id): 1045 # List of indices to delete. 1046 indices = [] 1047 1048 # Loop over the spins of the residue. 1049 for i in range(len(res.spin)): 1050 # Store the spin indices for deletion. 1051 if res.spin[i].num in spins or res.spin[i].name in spins: 1052 indices.append(i) 1053 1054 # Reverse the indices. 1055 indices.reverse() 1056 1057 # First prune the metadata. 1058 for index in indices: 1059 metadata_prune(mol_index=res._mol_index, res_index=res._res_index, spin_index=index) 1060 1061 # Delete the spins. 1062 for index in indices: 1063 res.spin.pop(index) 1064 1065 # Create an empty spin container if no spins remain. 1066 if len(res.spin) == 0: 1067 res.spin.add_item() 1068 1069 # Release the lock. 1070 finally: 1071 status.spin_lock.release(sys._getframe().f_code.co_name)
1072 1073
1074 -def display_molecule(mol_id=None):
1075 """Function for displaying the information associated with the molecule. 1076 1077 @param mol_id: The molecule identifier string. 1078 @type mol_id: str 1079 """ 1080 1081 # Split up the selection string. 1082 mol_token, res_token, spin_token = tokenise(mol_id) 1083 1084 # Disallowed selections. 1085 if res_token != None: 1086 raise RelaxResSelectDisallowError 1087 if spin_token != None: 1088 raise RelaxSpinSelectDisallowError 1089 1090 # The molecule selection string. 1091 if mol_token: 1092 mol_sel = '#' + mol_token 1093 else: 1094 mol_sel = None 1095 1096 # Print a header. 1097 print("\n\n%-15s %-15s" % ("Molecule", "Number of residues")) 1098 1099 # Molecule loop. 1100 for mol in molecule_loop(mol_sel): 1101 # Print the molecule data. 1102 print("%-15s %-15s" % (mol.name, repr(len(mol.res))))
1103 1104
1105 -def display_residue(res_id=None):
1106 """Function for displaying the information associated with the residue. 1107 1108 @param res_id: The molecule and residue identifier string. 1109 @type res_id: str 1110 """ 1111 1112 # Split up the selection string. 1113 mol_token, res_token, spin_token = tokenise(res_id) 1114 1115 # Disallow spin selections. 1116 if spin_token != None: 1117 raise RelaxSpinSelectDisallowError 1118 1119 # Print a header. 1120 print("\n\n%-15s %-15s %-15s %-15s" % ("Molecule", "Res number", "Res name", "Number of spins")) 1121 1122 # Residue loop. 1123 for res, mol_name in residue_loop(res_id, full_info=True): 1124 print("%-15s %-15s %-15s %-15s" % (mol_name, repr(res.num), res.name, repr(len(res.spin))))
1125 1126
1127 -def display_spin(spin_id=None):
1128 """Function for displaying the information associated with the spin. 1129 1130 @param spin_id: The molecule and residue identifier string. 1131 @type spin_id: str 1132 """ 1133 1134 # Print a header. 1135 print("\n\n%-15s %-15s %-15s %-15s %-15s" % ("Molecule", "Res number", "Res name", "Spin number", "Spin name")) 1136 1137 # Spin loop. 1138 for spin, mol_name, res_num, res_name in spin_loop(spin_id, full_info=True): 1139 # Print the residue data. 1140 print("%-15s %-15s %-15s %-15s %-15s" % (mol_name, repr(res_num), res_name, repr(spin.num), spin.name))
1141 1142
1143 -def exists_mol_res_spin_data(pipe=None):
1144 """Function for determining if any molecule-residue-spin data exists. 1145 1146 @keyword pipe: The data pipe in which the molecule-residue-spin data will be checked for. 1147 @type pipe: str 1148 @return: The answer to the question about the existence of data. 1149 @rtype: bool 1150 """ 1151 1152 # The current data pipe. 1153 if pipe == None: 1154 pipe = pipes.cdp_name() 1155 1156 # Test the data pipe. 1157 pipes.test(pipe) 1158 1159 # Get the data pipe. 1160 dp = pipes.get_pipe(pipe) 1161 1162 # The molecule, residue, spin object stack is empty. 1163 if dp.mol.is_empty(): 1164 return False 1165 1166 # Otherwise. 1167 return True
1168 1169
1170 -def find_index(selection=None, pipe=None, global_index=True):
1171 """Find and return the spin index or indices for the selection string. 1172 1173 @keyword selection: The spin selection identifier. 1174 @type selection: str 1175 @keyword pipe: The data pipe containing the spin. Defaults to the current data pipe. 1176 @type pipe: str 1177 @keyword global_index: A flag which if True will cause the global index to be returned. If False, then the molecule, residue, and spin indices will be returned. 1178 @type global_index: bool 1179 @return: The global spin index or the molecule, residue, and spin indices. 1180 @rtype: int or tuple of 3 int 1181 """ 1182 1183 # The data pipe. 1184 if pipe == None: 1185 pipe = pipes.cdp_name() 1186 1187 # Test the data pipe. 1188 pipes.test(pipe) 1189 1190 # Get the data pipe. 1191 dp = pipes.get_pipe(pipe) 1192 1193 # Parse the selection string. 1194 select_obj = Selection(selection) 1195 1196 # Init the mol and global index. 1197 global_i = -1 1198 mol_index = -1 1199 1200 # Loop over the molecules. 1201 for mol in dp.mol: 1202 # Increment the molecule index. 1203 mol_index = mol_index + 1 1204 1205 # Init the residue index. 1206 res_index = -1 1207 1208 # Loop over the residues. 1209 for res in mol.res: 1210 # Increment the residue index. 1211 res_index = res_index + 1 1212 1213 # Init the residue index. 1214 spin_index = -1 1215 1216 # Loop over the spins. 1217 for spin in res.spin: 1218 # Increment the spin and global index. 1219 spin_index = spin_index + 1 1220 global_i = global_i + 1 1221 1222 # Stop if the spin matches the selection. 1223 if select_obj.contains_spin(spin_num=spin.num, spin_name=spin.name, res_num=res.num, res_name=res.name, mol=mol.name): 1224 # Return the indices. 1225 if global_index: 1226 return global_i 1227 else: 1228 return mol_index, res_index, spin_index
1229 1230
1231 -def first_residue_num(selection=None):
1232 """Determine the first residue number. 1233 1234 @return: The number of the first residue. 1235 @rtype: int 1236 """ 1237 1238 # Get the molecule. 1239 mol = return_molecule(selection) 1240 1241 # The first residue number. 1242 return mol.res[0].num
1243 1244
1245 -def generate_spin_id(pipe_cont=None, pipe_name=None, mol_name=None, res_num=None, res_name=None, spin_num=None, spin_name=None):
1246 """Generate the spin selection string. 1247 1248 @keyword pipe_cont: The data pipe object. 1249 @type pipe_cont: PipeContainer instance 1250 @keyword pipe_name: The data pipe name. 1251 @type pipe_name: str 1252 @keyword mol_name: The molecule name. 1253 @type mol_name: str or None 1254 @keyword res_num: The residue number. 1255 @type res_num: int or None 1256 @keyword res_name: The residue name. 1257 @type res_name: str or None 1258 @keyword spin_num: The spin number. 1259 @type spin_num: int or None 1260 @keyword spin_name: The spin name. 1261 @type spin_name: str or None 1262 @return: The spin identification string. 1263 @rtype: str 1264 """ 1265 1266 # The data pipe. 1267 if pipe_cont == None: 1268 pipe_cont = pipes.get_pipe(pipe_name) 1269 1270 # Init. 1271 id = "" 1272 1273 # Molecule name and container. 1274 if mol_name != None: 1275 id = id + "#" + mol_name 1276 1277 # Residue data. 1278 res_num_id = '' 1279 res_name_id = '' 1280 if res_num != None: 1281 res_num_id = id + ":" + str(res_num) 1282 res_num_exists = res_num_id in pipe_cont.mol._spin_id_lookup 1283 if res_name != None: 1284 res_name_id = id + ":" + res_name 1285 res_name_exists = res_name_id in pipe_cont.mol._spin_id_lookup 1286 1287 # Select between the name and number, defaulting to the residue number if needed. 1288 if res_name != None and res_num != None: 1289 if res_num_exists and res_name_exists: 1290 id = res_num_id 1291 elif not res_num_exists or not res_name_exists: 1292 id = res_num_id 1293 elif res_num_exists: 1294 id = res_num_id 1295 elif res_name_exists: 1296 id = res_name_id 1297 elif res_num != None: 1298 id = res_num_id 1299 elif res_name != None: 1300 id = res_name_id 1301 elif res_num != None: 1302 id = res_num_id 1303 elif res_name != None: 1304 id = res_name_id 1305 1306 # Spin data. 1307 spin_num_id = '' 1308 spin_name_id = '' 1309 spin_num_exists = False 1310 spin_name_exists = False 1311 if spin_num != None: 1312 spin_num_id = id + "@" + str(spin_num) 1313 spin_num_exists = spin_num_id in pipe_cont.mol._spin_id_lookup 1314 if spin_name != None: 1315 spin_name_id = id + "@" + spin_name 1316 spin_name_exists = spin_name_id in pipe_cont.mol._spin_id_lookup 1317 1318 # Select between the name and number, defaulting to the spin name if needed. 1319 if spin_name != None and spin_num != None: 1320 if spin_num_exists and spin_name_exists: 1321 id = spin_name_id 1322 elif not spin_num_exists or not spin_name_exists: 1323 id = spin_name_id 1324 elif spin_name_exists: 1325 id = spin_name_id 1326 elif spin_num_exists: 1327 id = spin_num_id 1328 elif spin_name != None: 1329 id = spin_name_id 1330 elif spin_num != None: 1331 id = spin_num_id 1332 elif spin_name != None: 1333 id = spin_name_id 1334 elif spin_num != None: 1335 id = spin_num_id 1336 1337 # Return the full spin ID string. 1338 return id
1339 1340
1341 -def generate_spin_id_data_array(data=None, mol_name_col=None, res_num_col=None, res_name_col=None, spin_num_col=None, spin_name_col=None):
1342 """Generate the spin selection string from the given data array. 1343 1344 @param data: An array containing the molecule, residue, and/or spin data. 1345 @type data: list of str 1346 @param mol_name_col: The column containing the molecule name information. 1347 @type mol_name_col: int or None 1348 @param res_name_col: The column containing the residue name information. 1349 @type res_name_col: int or None 1350 @param res_num_col: The column containing the residue number information. 1351 @type res_num_col: int or None 1352 @param spin_name_col: The column containing the spin name information. 1353 @type spin_name_col: int or None 1354 @param spin_num_col: The column containing the spin number information. 1355 @type spin_num_col: int or None 1356 @return: The spin identification string. 1357 @rtype: str 1358 """ 1359 1360 # Init. 1361 id = "" 1362 1363 # Molecule data. 1364 if mol_name_col and data[mol_name_col-1] not in [None, 'None']: 1365 id = id + "#" + data[mol_name_col-1] 1366 1367 # Residue data. 1368 if res_num_col and data[res_num_col-1] not in [None, 'None']: 1369 id = id + ":" + str(data[res_num_col-1]) 1370 elif res_name_col and data[res_name_col-1] not in [None, 'None']: 1371 id = id + ":" + data[res_name_col-1] 1372 1373 # Spin data. 1374 if spin_num_col and data[spin_num_col-1] not in [None, 'None']: 1375 id = id + "@" + str(data[spin_num_col-1]) 1376 elif spin_name_col and data[spin_name_col-1] not in [None, 'None']: 1377 id = id + "@" + data[spin_name_col-1] 1378 1379 # Return the spin id string. 1380 return id
1381 1382
1383 -def generate_spin_id_unique(pipe_cont=None, pipe_name=None, mol=None, res=None, spin=None, mol_name=None, res_num=None, res_name=None, spin_num=None, spin_name=None):
1384 """Generate a list of spin ID variants for the given set of molecule, residue and spin indices. 1385 1386 @keyword pipe_cont: The data pipe object. 1387 @type pipe_cont: PipeContainer instance 1388 @keyword pipe_name: The data pipe name. 1389 @type pipe_name: str 1390 @keyword mol: The molecule container. 1391 @type mol: MoleculeContainer instance 1392 @keyword res: The residue container. 1393 @type res: ResidueContainer instance 1394 @keyword spin: The spin container. 1395 @type spin: SpinContainer instance 1396 @keyword mol_name: The molecule name (an alternative to the molecule container). 1397 @type mol_name: str or None 1398 @keyword res_num: The residue number (an alternative to the residue container). 1399 @type res_num: int or None 1400 @keyword res_name: The residue name (an alternative to the residue container). 1401 @type res_name: str or None 1402 @keyword spin_num: The spin number (an alternative to the spin container). 1403 @type spin_num: int or None 1404 @keyword spin_name: The spin name (an alternative to the spin container). 1405 @type spin_name: str or None 1406 @return: The unique spin ID. 1407 @rtype: str 1408 """ 1409 1410 # The data pipe. 1411 if pipe_cont == None: 1412 pipe_cont = pipes.get_pipe(pipe_name) 1413 1414 # Get the containers if needed. 1415 if mol == None: 1416 mol = return_molecule_by_name(pipe_cont=pipe_cont, mol_name=mol_name) 1417 if mol != None and res == None: 1418 if res_name != None or res_num != None: 1419 res = return_residue_by_info(mol=mol, res_name=res_name, res_num=res_num) 1420 elif len(mol.res) == 1: 1421 res = mol.res[0] 1422 if res != None and spin == None: 1423 if spin_name != None or spin_num != None: 1424 spin = return_spin_by_info(res=res, spin_name=spin_name, spin_num=spin_num) 1425 elif len(res.spin) == 1: 1426 spin = res.spin[0] 1427 1428 # The info. 1429 if mol: 1430 mol_name = mol.name 1431 if res: 1432 res_name = res.name 1433 res_num = res.num 1434 if spin: 1435 spin_name = spin.name 1436 spin_num = spin.num 1437 1438 # Unique info. 1439 unique_res_name = True 1440 if res and res.name != None and mol._res_name_count[res.name] > 1: 1441 unique_res_name = False 1442 unique_res_num = True 1443 if res and res.num != None and mol._res_num_count[res.num] > 1: 1444 unique_res_num = False 1445 unique_spin_name = True 1446 if spin and spin.name != None and res._spin_name_count[spin.name] > 1: 1447 unique_spin_name = False 1448 unique_spin_num = True 1449 if spin and spin.num != None and res._spin_num_count[spin.num] > 1: 1450 unique_spin_num = False 1451 1452 # The unique ID. 1453 if unique_res_num and unique_spin_name: 1454 return generate_spin_id(pipe_cont=pipe_cont, mol_name=mol_name, res_num=res_num, spin_name=spin_name) 1455 if unique_res_num and unique_spin_num: 1456 return generate_spin_id(pipe_cont=pipe_cont, mol_name=mol_name, res_num=res_num, spin_num=spin_num) 1457 if unique_res_name and unique_spin_num: 1458 return generate_spin_id(pipe_cont=pipe_cont, mol_name=mol_name, res_name=res_name, spin_num=spin_num) 1459 if unique_res_name and unique_spin_name: 1460 return generate_spin_id(pipe_cont=pipe_cont, mol_name=mol_name, res_name=res_name, spin_name=spin_name)
1461 1462
1463 -def get_molecule_ids(selection=None):
1464 """Return a list of the molecule ID strings. 1465 1466 @param selection: The molecule selection identifier. 1467 @type selection: str 1468 @return: The molecule ID strings. 1469 @rtype: list of str 1470 """ 1471 1472 # No data pipes, so return an empty list without throwing an error. 1473 if not pipes.cdp_name(): 1474 return [] 1475 1476 # Loop over the molecules, append the ID of each within the selection. 1477 mol_ids = [] 1478 for mol, mol_id in molecule_loop(selection, return_id=True): 1479 mol_ids.append(mol_id) 1480 1481 # Return the IDs. 1482 return mol_ids
1483 1484
1485 -def get_molecule_names(selection=None):
1486 """Return a list of the molecule names. 1487 1488 @param selection: The molecule selection identifier. 1489 @type selection: str 1490 @return: The molecule names. 1491 @rtype: list of str 1492 """ 1493 1494 # No data pipes, so return an empty list without throwing an error. 1495 if not pipes.cdp_name(): 1496 return [] 1497 1498 # Loop over the molecules, append the name of each within the selection. 1499 mol_names = [] 1500 for mol in molecule_loop(selection): 1501 mol_names.append(mol.name) 1502 1503 # Return the names. 1504 return mol_names
1505 1506
1507 -def get_residue_ids(selection=None):
1508 """Return a list of the residue ID strings. 1509 1510 @param selection: The molecule and residue selection identifier. 1511 @type selection: str 1512 @return: The residue ID strings. 1513 @rtype: list of str 1514 """ 1515 1516 # No data pipes, so return an empty list without throwing an error. 1517 if not pipes.cdp_name(): 1518 return [] 1519 1520 # Loop over the residues, appending the ID of each within the selection. 1521 res_ids = [] 1522 for res, res_id in residue_loop(selection, return_id=True): 1523 res_ids.append(res_id) 1524 1525 # Return the IDs. 1526 return res_ids
1527 1528
1529 -def get_residue_names(selection=None):
1530 """Return a list of the residue names. 1531 1532 @param selection: The molecule and residue selection identifier. 1533 @type selection: str 1534 @return: The residue names. 1535 @rtype: list of str 1536 """ 1537 1538 # No data pipes, so return an empty list without throwing an error. 1539 if not pipes.cdp_name(): 1540 return [] 1541 1542 # Loop over the residues, appending the name of each within the selection. 1543 res_names = [] 1544 for res in residue_loop(selection): 1545 res_names.append(res.name) 1546 1547 # Return the names. 1548 return res_names
1549 1550
1551 -def get_residue_nums(selection=None):
1552 """Return a list of the residue numbers. 1553 1554 @param selection: The molecule and residue selection identifier. 1555 @type selection: str 1556 @return: The residue numbers. 1557 @rtype: list of str 1558 """ 1559 1560 # No data pipes, so return an empty list without throwing an error. 1561 if not pipes.cdp_name(): 1562 return [] 1563 1564 # Loop over the residues, appending the number of each within the selection. 1565 res_nums = [] 1566 for res in residue_loop(selection): 1567 res_nums.append(res.num) 1568 1569 # Return the numbers. 1570 return res_nums
1571 1572
1573 -def get_spin_ids(selection=None):
1574 """Return a list of the spin ID strings. 1575 1576 @param selection: The molecule and spin selection identifier. 1577 @type selection: str 1578 @return: The spin ID strings. 1579 @rtype: list of str 1580 """ 1581 1582 # No data pipes, so return an empty list without throwing an error. 1583 if not pipes.cdp_name(): 1584 return [] 1585 1586 # Loop over the spins, appending the ID of each within the selection. 1587 spin_ids = [] 1588 for spin, spin_id in spin_loop(selection, return_id=True): 1589 spin_ids.append(spin_id) 1590 1591 # Return the IDs. 1592 return spin_ids
1593 1594
1595 -def is_pseudoatom(spin=None):
1596 """Check if the given spin container corresponds to a pseudo-atom. 1597 1598 @keyword spin: The spin container to check. 1599 @type spin: SpinContainer instance 1600 @return: True if this is a pseudo-atom, False otherwise. 1601 @rtype: bool 1602 """ 1603 1604 # Check for the 'members' data structure. 1605 if hasattr(spin, 'members'): 1606 return True 1607 1608 # Normal atom. 1609 return False
1610 1611
1612 -def index_molecule(mol_name=None, pipe=None):
1613 """Return the index of the molecule of the given name. 1614 1615 @keyword mol_name: The name of the molecule. 1616 @type mol_name: str or None 1617 @keyword pipe: The data pipe, defaulting to the current data pipe. 1618 @type pipe: str or None 1619 @return: The index of the molecule, if it exists. 1620 @rtype: int or None 1621 """ 1622 1623 # The data pipe. 1624 if pipe == None: 1625 pipe = pipes.cdp_name() 1626 1627 # Test the data pipe. 1628 pipes.test(pipe) 1629 1630 # Get the data pipe. 1631 dp = pipes.get_pipe(pipe) 1632 1633 # Single molecule and no name given. 1634 if mol_name == None and len(dp.mol) == 1: 1635 return 0 1636 1637 # Loop over the molecules. 1638 i = 0 1639 for mol in dp.mol: 1640 # A match. 1641 if mol.name == mol_name: 1642 return i 1643 1644 # Increment the index. 1645 i += 1 1646 1647 # Nothing found. 1648 return None
1649 1650
1651 -def index_residue(res_num=None, res_name=None, mol_index=None, pipe=None):
1652 """Return the index of the residue. 1653 1654 @keyword res_num: The number of the residue. 1655 @type res_num: int 1656 @keyword res_name: The name of the residue. 1657 @type res_name: str 1658 @keyword mol_index: The index of the molecule. 1659 @type mol_index: str 1660 @keyword pipe: The data pipe, defaulting to the current data pipe. 1661 @type pipe: str or None 1662 @return: The index of the residue, if it exists. 1663 @rtype: int or None 1664 """ 1665 1666 # The data pipe. 1667 if pipe == None: 1668 pipe = pipes.cdp_name() 1669 1670 # Test the data pipe. 1671 pipes.test(pipe) 1672 1673 # Get the data pipe. 1674 dp = pipes.get_pipe(pipe) 1675 1676 # Single unnamed residue. 1677 if len(dp.mol[mol_index].res) == 1 and res_num == dp.mol[mol_index].res[0].num and res_name == dp.mol[mol_index].res[0].name: 1678 return 0 1679 1680 # Loop over the residues. 1681 i = 0 1682 for res in dp.mol[mol_index].res: 1683 # A unique number match. 1684 if res_num != None and res.num == res_num: 1685 return i 1686 1687 # Match names, if no number is given. 1688 if res_num == None and res_name != None and res.name == res_name: 1689 return i 1690 1691 # Increment the index. 1692 i += 1 1693 1694 # Nothing found. 1695 return None
1696 1697
1698 -def last_residue_num(selection=None):
1699 """Determine the last residue number. 1700 1701 @param selection: The molecule selection identifier. 1702 @type selection: str 1703 @return: The number of the last residue. 1704 @rtype: int 1705 """ 1706 1707 # Get the molecule. 1708 mol = return_molecule(selection) 1709 1710 # The last residue number. 1711 return mol.res[-1].num
1712 1713
1714 -def linear_ave(positions):
1715 """Perform linear averaging of the atomic positions. 1716 1717 @param positions: The atomic positions. The first index is that of the positions to be averaged over. The second index is over the different models. The last index is over the x, y, and z coordinates. 1718 @type positions: list of lists of numpy float arrays 1719 @return: The averaged positions as a list of vectors. 1720 @rtype: list of numpy float arrays 1721 """ 1722 1723 # Loop over the multiple models. 1724 ave = [] 1725 for model_index in range(len(positions[0])): 1726 # Append an empty vector. 1727 ave.append(array([0.0, 0.0, 0.0])) 1728 1729 # Loop over the x, y, and z coordinates. 1730 for coord_index in range(3): 1731 # Loop over the atomic positions. 1732 for atom_index in range(len(positions)): 1733 ave[model_index][coord_index] = ave[model_index][coord_index] + positions[atom_index][model_index][coord_index] 1734 1735 # Average. 1736 ave[model_index][coord_index] = ave[model_index][coord_index] / len(positions) 1737 1738 # Return the averaged positions. 1739 return ave
1740 1741
1742 -def metadata_cleanup(mol_index=None, res_index=None, spin_index=None, pipe=None):
1743 """Prune all of the metadata matching the given indices. 1744 1745 @keyword mol_index: The index of the molecule to prune. If not supplied, all molecules will be pruned. 1746 @type mol_index: int or None 1747 @keyword res_index: The index of the residue to prune. If not supplied, all residues of the matching molecules will be pruned. 1748 @type res_index: int or None 1749 @keyword spin_index: The index of the spin to prune. If not supplied, all spins of the matching residues will be pruned. 1750 @type spin_index: int or None 1751 @keyword pipe: The data pipe to update, defaulting to the current data pipe. 1752 @type pipe: str or None 1753 """ 1754 1755 # The data pipe. 1756 if pipe == None: 1757 pipe = pipes.cdp_name() 1758 1759 # Test the data pipe. 1760 pipes.test(pipe) 1761 1762 # Get the data pipe. 1763 dp = pipes.get_pipe(pipe) 1764 1765 # Update the metadata info counts. 1766 metadata_counts(pipe_cont=dp) 1767 1768 # Loop over the molecules. 1769 to_remove = [] 1770 for i in range(len(dp.mol)): 1771 # Molecule skipping. 1772 if mol_index != None and mol_index != i: 1773 continue 1774 1775 # Alias. 1776 mol = dp.mol[i] 1777 1778 # Loop over the residues. 1779 for j in range(len(mol.res)): 1780 # Residue skipping. 1781 if res_index != None and res_index != j: 1782 continue 1783 1784 # Alias. 1785 res = mol.res[j] 1786 1787 # Loop over the spins. 1788 for k in range(len(res.spin)): 1789 # Spin skipping. 1790 if spin_index != None and spin_index != k: 1791 continue 1792 1793 # Alias. 1794 spin = res.spin[k] 1795 1796 # The list of IDs to remove. 1797 to_remove = spin_id_variants_cleanup(dp=dp, mol_index=i, res_index=j, spin_index=k) 1798 1799 # ID removal. 1800 for spin_id in to_remove: 1801 # Blank IDs. 1802 if spin_id == '': 1803 continue 1804 1805 # Remove from the list in the spin container itself. 1806 if spin_id in spin._spin_ids: 1807 spin._spin_ids.pop(spin._spin_ids.index(spin_id)) 1808 1809 # Remove the IDs from the look up table. 1810 if spin_id in dp.mol._spin_id_lookup: 1811 dp.mol._spin_id_lookup.pop(spin_id)
1812 1813
1814 -def metadata_counts(pipe_cont=None):
1815 """Update the molecule, residue, and spin name and number count metadata. 1816 1817 @keyword pipe_cont: The data pipe object. 1818 @type pipe_cont: PipeContainer instance 1819 """ 1820 1821 # The top level counts. 1822 pipe_cont.mol._res_name_count = {} 1823 pipe_cont.mol._res_num_count = {} 1824 pipe_cont.mol._spin_name_count = {} 1825 pipe_cont.mol._spin_num_count = {} 1826 1827 # Pre-parse: Update the metadata for determining if names and numbers already exist. 1828 for i in range(len(pipe_cont.mol)): 1829 # Alias. 1830 mol = pipe_cont.mol[i] 1831 1832 # The molecule level counts. 1833 mol._res_name_count = {} 1834 mol._res_num_count = {} 1835 mol._spin_name_count = {} 1836 mol._spin_num_count = {} 1837 1838 # Loop over the residues. 1839 for j in range(len(mol.res)): 1840 # Alias. 1841 res = mol.res[j] 1842 1843 # Count the residue names. 1844 if res.name != None: 1845 # Top level. 1846 if res.name not in pipe_cont.mol._res_name_count: 1847 pipe_cont.mol._res_name_count[res.name] = 1 1848 else: 1849 pipe_cont.mol._res_name_count[res.name] += 1 1850 1851 # Molecule level. 1852 if res.name not in mol._res_name_count: 1853 mol._res_name_count[res.name] = 1 1854 else: 1855 mol._res_name_count[res.name] += 1 1856 1857 # Count the residue numbers. 1858 if res.num != None: 1859 # Top level. 1860 if res.num not in pipe_cont.mol._res_num_count: 1861 pipe_cont.mol._res_num_count[res.num] = 1 1862 else: 1863 pipe_cont.mol._res_num_count[res.num] += 1 1864 1865 # Molecule level. 1866 if res.num not in mol._res_num_count: 1867 mol._res_num_count[res.num] = 1 1868 else: 1869 mol._res_num_count[res.num] += 1 1870 1871 # The residue level counts. 1872 res._spin_name_count = {} 1873 res._spin_num_count = {} 1874 1875 # Loop over the spins. 1876 for k in range(len(res.spin)): 1877 # Alias. 1878 spin = res.spin[k] 1879 1880 # Count the spin names. 1881 if spin.name != None: 1882 # Top level. 1883 if spin.name not in pipe_cont.mol._spin_name_count: 1884 pipe_cont.mol._spin_name_count[spin.name] = 1 1885 else: 1886 pipe_cont.mol._spin_name_count[spin.name] += 1 1887 1888 # Molecule level. 1889 if spin.name not in mol._spin_name_count: 1890 mol._spin_name_count[spin.name] = 1 1891 else: 1892 mol._spin_name_count[spin.name] += 1 1893 1894 # Residue level. 1895 if spin.name not in res._spin_name_count: 1896 res._spin_name_count[spin.name] = 1 1897 else: 1898 res._spin_name_count[spin.name] += 1 1899 1900 # Count the spin numbers. 1901 if spin.num != None: 1902 # Top level. 1903 if spin.num not in pipe_cont.mol._spin_num_count: 1904 pipe_cont.mol._spin_num_count[spin.num] = 1 1905 else: 1906 pipe_cont.mol._spin_num_count[spin.num] += 1 1907 1908 # Molecule level. 1909 if spin.num not in mol._spin_num_count: 1910 mol._spin_num_count[spin.num] = 1 1911 else: 1912 mol._spin_num_count[spin.num] += 1 1913 1914 # Residue level. 1915 if spin.num not in res._spin_num_count: 1916 res._spin_num_count[spin.num] = 1 1917 else: 1918 res._spin_num_count[spin.num] += 1
1919 1920
1921 -def metadata_prune(mol_index=None, res_index=None, spin_index=None, pipe=None):
1922 """Prune all of the metadata matching the given indices. 1923 1924 @keyword mol_index: The index of the molecule to prune. If not supplied, all molecules will be pruned. 1925 @type mol_index: int or None 1926 @keyword res_index: The index of the residue to prune. If not supplied, all residues of the matching molecules will be pruned. 1927 @type res_index: int or None 1928 @keyword spin_index: The index of the spin to prune. If not supplied, all spins of the matching residues will be pruned. 1929 @type spin_index: int or None 1930 @keyword pipe: The data pipe to update, defaulting to the current data pipe. 1931 @type pipe: str or None 1932 """ 1933 1934 # The data pipe. 1935 if pipe == None: 1936 pipe = pipes.cdp_name() 1937 1938 # Test the data pipe. 1939 pipes.test(pipe) 1940 1941 # Get the data pipe. 1942 dp = pipes.get_pipe(pipe) 1943 1944 # Update the metadata info counts. 1945 metadata_counts(pipe_cont=dp) 1946 1947 # Loop over the molecules. 1948 to_remove = [] 1949 for i in range(len(dp.mol)): 1950 # Molecule skipping. 1951 if mol_index != None and mol_index != i: 1952 continue 1953 1954 # Alias. 1955 mol = dp.mol[i] 1956 1957 # Loop over the residues. 1958 for j in range(len(mol.res)): 1959 # Residue skipping. 1960 if res_index != None and res_index != j: 1961 continue 1962 1963 # Alias. 1964 res = mol.res[j] 1965 1966 # Loop over the spins. 1967 for k in range(len(res.spin)): 1968 # Spin skipping. 1969 if spin_index != None and spin_index != k: 1970 continue 1971 1972 # Alias. 1973 spin = res.spin[k] 1974 1975 # The list of IDs to remove. 1976 to_remove = spin_id_variants_prune(dp=dp, mol_index=i, res_index=j, spin_index=k) 1977 1978 # ID removal. 1979 for spin_id in to_remove: 1980 # Blank IDs. 1981 if spin_id == '': 1982 continue 1983 1984 # Remove from the list in the spin container itself. 1985 if spin_id in spin._spin_ids: 1986 spin._spin_ids.pop(spin._spin_ids.index(spin_id)) 1987 1988 # Remove the IDs from the look up table. 1989 if spin_id in dp.mol._spin_id_lookup: 1990 dp.mol._spin_id_lookup.pop(spin_id)
1991 1992
1993 -def metadata_update(mol_index=None, res_index=None, spin_index=None, pipe=None):
1994 """Update all of the private look up metadata for the given containers. 1995 1996 @keyword mol_index: The index of the molecule to update. If not supplied, all molecules will be updated. 1997 @type mol_index: int or None 1998 @keyword res_index: The index of the residue to update. If not supplied, all residues will be updated. 1999 @type res_index: int or None 2000 @keyword spin_index: The index of the spin to update. If not supplied, all spins will be updated. 2001 @type spin_index: int or None 2002 @keyword pipe: The data pipe to update, defaulting to the current data pipe. 2003 @type pipe: str or None 2004 """ 2005 2006 # The data pipe. 2007 if pipe == None: 2008 pipe = pipes.cdp_name() 2009 2010 # Test the data pipe. 2011 pipes.test(pipe) 2012 2013 # Get the data pipe. 2014 dp = pipes.get_pipe(pipe) 2015 2016 # Update the metadata info counts. 2017 metadata_counts(pipe_cont=dp) 2018 2019 # Loop over the molecules. 2020 for i in range(len(dp.mol)): 2021 # Molecule skipping. 2022 if mol_index != None and mol_index != i: 2023 continue 2024 2025 # Alias. 2026 mol = dp.mol[i] 2027 2028 # Update the molecule metadata. 2029 mol._mol_index = i 2030 2031 # Loop over the residues. 2032 for j in range(len(mol.res)): 2033 # Residue skipping. 2034 if res_index != None and res_index != j: 2035 continue 2036 2037 # Alias. 2038 res = mol.res[j] 2039 2040 # Update the residue metadata. 2041 res._mol_name = mol.name 2042 res._mol_index = i 2043 res._res_index = j 2044 2045 # Loop over the spins. 2046 for k in range(len(res.spin)): 2047 # Spin skipping. 2048 if spin_index != None and spin_index != k: 2049 continue 2050 2051 # Alias. 2052 spin = res.spin[k] 2053 2054 # Update the spin metadata. 2055 spin._mol_name = mol.name 2056 spin._mol_index = i 2057 spin._res_name = res.name 2058 spin._res_num = res.num 2059 spin._res_index = j 2060 spin._spin_index = k 2061 2062 # The list of IDs to store. 2063 spin_ids = spin_id_variants(dp=dp, mol_index=i, res_index=j, spin_index=k) 2064 2065 # ID storage. 2066 spin._spin_ids = [] 2067 for spin_id in spin_ids: 2068 # Blank IDs. 2069 if spin_id == '': 2070 continue 2071 2072 # Store the list in the spin container itself. 2073 spin._spin_ids.append(spin_id) 2074 2075 # Update the look up table. 2076 dp.mol._spin_id_lookup[spin_id] = [i, j, k]
2077 2078
2079 -def molecule_loop(selection=None, pipe=None, return_id=False):
2080 """Generator function for looping over all the molecules of the given selection. 2081 2082 @param selection: The molecule selection identifier. 2083 @type selection: str 2084 @param pipe: The data pipe containing the molecule. Defaults to the current data pipe. 2085 @type pipe: str 2086 @keyword return_id: A flag which if True will cause the molecule identification string of the molecule spin to be returned in addition to the spin container. 2087 @type return_id: bool 2088 @return: The molecule specific data container. 2089 @rtype: instance of the MoleculeContainer class. 2090 """ 2091 2092 # The data pipe. 2093 if pipe == None: 2094 pipe = pipes.cdp_name() 2095 2096 # Test the data pipe. 2097 pipes.test(pipe) 2098 2099 # Get the data pipe. 2100 dp = pipes.get_pipe(pipe) 2101 2102 # Test for the presence of data, and end the execution of this function if there is none. 2103 if not exists_mol_res_spin_data(pipe=pipe): 2104 return 2105 2106 # Parse the selection string. 2107 select_obj = Selection(selection) 2108 2109 # Loop over the molecules. 2110 for mol in dp.mol: 2111 # Skip the molecule if there is no match to the selection. 2112 if not select_obj.contains_mol(mol.name): 2113 continue 2114 2115 # Generate the spin id. 2116 if return_id: 2117 mol_id = generate_spin_id(pipe_cont=dp, mol_name=mol.name) 2118 2119 # Yield the molecule data container. 2120 if return_id: 2121 yield mol, mol_id 2122 else: 2123 yield mol
2124 2125
2126 -def name_molecule(mol_id, name=None, force=False):
2127 """Name the molecules. 2128 2129 @param mol_id: The molecule identification string. 2130 @type mol_id: str 2131 @param name: The new molecule name. 2132 @type name: str 2133 @keyword force: A flag which if True will cause the named molecule to be renamed. 2134 @type force: bool 2135 """ 2136 2137 # Acquire the spin lock (data modifying function), and make sure it is finally released. 2138 status.spin_lock.acquire(sys._getframe().f_code.co_name) 2139 try: 2140 2141 # Get the single molecule data container. 2142 mol = return_molecule(mol_id) 2143 2144 # Disallow residue and spin selections. 2145 select_obj = Selection(mol_id) 2146 if select_obj.has_residues(): 2147 raise RelaxResSelectDisallowError 2148 if select_obj.has_spins(): 2149 raise RelaxSpinSelectDisallowError 2150 2151 # Name the molecule is there is a single match. 2152 if mol: 2153 if mol.name and not force: 2154 warn(RelaxWarning("The molecule '%s' is already named. Set the force flag to rename." % mol_id)) 2155 else: 2156 mol.name = name 2157 2158 # Update the private metadata. 2159 metadata_cleanup(mol_index=mol._mol_index) 2160 metadata_update(mol_index=mol._mol_index) 2161 2162 # Release the lock. 2163 finally: 2164 status.spin_lock.release(sys._getframe().f_code.co_name)
2165 2166
2167 -def name_residue(res_id, name=None, force=False):
2168 """Name the residues. 2169 2170 @param res_id: The residue identification string. 2171 @type res_id: str 2172 @param name: The new residue name. 2173 @type name: str 2174 @keyword force: A flag which if True will cause the named residue to be renamed. 2175 @type force: bool 2176 """ 2177 2178 # Acquire the spin lock (data modifying function), and make sure it is finally released. 2179 status.spin_lock.acquire(sys._getframe().f_code.co_name) 2180 try: 2181 # Disallow spin selections. 2182 select_obj = Selection(res_id) 2183 if select_obj.has_spins(): 2184 raise RelaxSpinSelectDisallowError 2185 2186 # Rename the matching residues. 2187 for res, mol_name in residue_loop(res_id, full_info=True): 2188 if res.name and not force: 2189 warn(RelaxWarning("The residue '%s' is already named. Set the force flag to rename." % generate_spin_id(mol_name=mol_name, res_num=res.num, res_name=res.name))) 2190 else: 2191 res.name = name 2192 2193 # Update the private metadata. 2194 metadata_cleanup(mol_index=res._mol_index, res_index=res._res_index) 2195 metadata_update(mol_index=res._mol_index, res_index=res._res_index) 2196 2197 # Release the lock. 2198 finally: 2199 status.spin_lock.release(sys._getframe().f_code.co_name)
2200 2201
2202 -def name_spin(spin_id=None, name=None, pipe=None, force=False):
2203 """Name the spins. 2204 2205 @keyword spin_id: The spin identification string. 2206 @type spin_id: str 2207 @keyword name: The new spin name. 2208 @type name: str 2209 @param pipe: The data pipe to operate on. Defaults to the current data pipe. 2210 @type pipe: str 2211 @keyword force: A flag which if True will cause the named spin to be renamed. If None, then the warning messages will not mention the need to change this flag to rename. 2212 @type force: bool or None 2213 """ 2214 2215 # The data pipe. 2216 if pipe == None: 2217 pipe = pipes.cdp_name() 2218 2219 # Test the data pipe. 2220 pipes.test(pipe) 2221 2222 # Acquire the spin lock (data modifying function), and make sure it is finally released. 2223 status.spin_lock.acquire(sys._getframe().f_code.co_name) 2224 try: 2225 # Rename the matching spins. 2226 for spin, id in spin_loop(spin_id, pipe=pipe, return_id=True): 2227 if spin.name and force != True: 2228 if force == False: 2229 warn(RelaxWarning("The spin '%s' is already named. Set the force flag to rename." % id)) 2230 else: 2231 warn(RelaxWarning("The spin '%s' is already named." % id)) 2232 else: 2233 spin.name = name 2234 2235 # Update the private metadata. 2236 metadata_cleanup(mol_index=spin._mol_index, res_index=spin._res_index, spin_index=spin._spin_index) 2237 metadata_update(mol_index=spin._mol_index, res_index=spin._res_index, spin_index=spin._spin_index) 2238 2239 # Release the lock. 2240 finally: 2241 status.spin_lock.release(sys._getframe().f_code.co_name)
2242 2243
2244 -def number_residue(res_id, number=None, force=False):
2245 """Number the residues. 2246 2247 @param res_id: The residue identification string. 2248 @type res_id: str 2249 @param number: The new residue number. 2250 @type number: int 2251 @keyword force: A flag which if True will cause the numbered residue to be renumbered. 2252 @type force: bool 2253 """ 2254 2255 # Acquire the spin lock (data modifying function), and make sure it is finally released. 2256 status.spin_lock.acquire(sys._getframe().f_code.co_name) 2257 try: 2258 # Catch multiple numberings! 2259 i = 0 2260 for res in residue_loop(res_id): 2261 i = i + 1 2262 2263 # Fail if multiple residues are numbered. 2264 if i > 1: 2265 raise RelaxError("The numbering of multiple residues is disallowed, each residue requires a unique number.") 2266 2267 # Disallow spin selections. 2268 select_obj = Selection(res_id) 2269 if select_obj.has_spins(): 2270 raise RelaxSpinSelectDisallowError 2271 2272 # Rename the residue. 2273 for res, mol_name in residue_loop(res_id, full_info=True): 2274 if res.num and not force: 2275 warn(RelaxWarning("The residue '%s' is already numbered. Set the force flag to renumber." % generate_spin_id(mol_name=mol_name, res_num=res.num, res_name=res.name))) 2276 else: 2277 res.num = number 2278 2279 # Update the private metadata. 2280 metadata_cleanup(mol_index=res._mol_index, res_index=res._res_index) 2281 metadata_update(mol_index=res._mol_index, res_index=res._res_index) 2282 2283 # Release the lock. 2284 finally: 2285 status.spin_lock.release(sys._getframe().f_code.co_name)
2286 2287
2288 -def number_spin(spin_id=None, number=None, force=False):
2289 """Number the spins. 2290 2291 @param spin_id: The spin identification string. 2292 @type spin_id: str 2293 @param number: The new spin number. 2294 @type number: int 2295 @keyword force: A flag which if True will cause the numbered spin to be renumbered. 2296 @type force: bool 2297 """ 2298 2299 # Acquire the spin lock (data modifying function), and make sure it is finally released. 2300 status.spin_lock.acquire(sys._getframe().f_code.co_name) 2301 try: 2302 # Catch multiple renumberings! 2303 i = 0 2304 for spin in spin_loop(spin_id): 2305 i = i + 1 2306 2307 # Fail if multiple spins are numbered. 2308 if number != None and i > 1: 2309 raise RelaxError("The numbering of multiple spins is disallowed, as each spin requires a unique number.") 2310 2311 # Rename the spin. 2312 for spin, id in spin_loop(spin_id, return_id=True): 2313 if spin.num and not force: 2314 warn(RelaxWarning("The spin '%s' is already numbered. Set the force flag to renumber." % id)) 2315 else: 2316 spin.num = number 2317 2318 # Update the private metadata. 2319 metadata_cleanup(mol_index=spin._mol_index, res_index=spin._res_index, spin_index=spin._spin_index) 2320 metadata_update(mol_index=spin._mol_index, res_index=spin._res_index, spin_index=spin._spin_index) 2321 2322 # Release the lock. 2323 finally: 2324 status.spin_lock.release(sys._getframe().f_code.co_name)
2325 2326
2327 -def one_letter_code(res_names):
2328 """Convert the list of residue names into a string of one letter residue codes. 2329 2330 Standard amino acids are converted to the one letter code. Unknown residues are labelled as 'X'. 2331 2332 2333 @param res_names: A list of residue names. 2334 @type res_names: list or str 2335 @return: The one letter codes for the residues. 2336 @rtype: str 2337 """ 2338 2339 # The amino acid translation table. 2340 aa_table = [ 2341 ['Alanine', 'ALA', 'A'], 2342 ['Arginine', 'ARG', 'R'], 2343 ['Asparagine', 'ASN', 'N'], 2344 ['Aspartic acid', 'ASP', 'D'], 2345 ['Cysteine', 'CYS', 'C'], 2346 ['Glutamic acid', 'GLU', 'E'], 2347 ['Glutamine', 'GLN', 'Q'], 2348 ['Glycine', 'GLY', 'G'], 2349 ['Histidine', 'HIS', 'H'], 2350 ['Isoleucine', 'ILE', 'I'], 2351 ['Leucine', 'LEU', 'L'], 2352 ['Lysine', 'LYS', 'K'], 2353 ['Methionine', 'MET', 'M'], 2354 ['Phenylalanine', 'PHE', 'F'], 2355 ['Proline', 'PRO', 'P'], 2356 ['Serine', 'SER', 'S'], 2357 ['Threonine', 'THR', 'T'], 2358 ['Tryptophan', 'TRP', 'W'], 2359 ['Tyrosine', 'TYR', 'Y'], 2360 ['Valine', 'VAL', 'V'] 2361 ] 2362 2363 # Translate. 2364 seq = '' 2365 for res in res_names: 2366 # Aa match. 2367 match = False 2368 for i in range(len(aa_table)): 2369 if res.upper() == aa_table[i][1]: 2370 seq = seq + aa_table[i][2] 2371 match = True 2372 break 2373 2374 # No match. 2375 if not match: 2376 seq = seq + 'X' 2377 2378 # Return the sequence. 2379 return seq
2380 2381
2382 -def pseudoatom_loop(spin=None, return_id=False):
2383 """Loop over the atoms of the given pseudo-atom spin container. 2384 2385 @keyword spin: The pseudo-atom spin container. 2386 @type spin: SpinContainer instance 2387 @keyword return_id: A flag which if True will cause the spin identification string of the current spin to be returned in addition to the spin container. 2388 @type return_id: bool 2389 @return: The spins of the pseudo-atom. 2390 @rtype: SpinContainer instance 2391 """ 2392 2393 # Check for the 'members' data structure. 2394 if not hasattr(spin, 'members'): 2395 return 2396 2397 # Loop over the members. 2398 for spin_id in spin.members: 2399 # Get the spin container. 2400 spin = return_spin(spin_id=spin_id) 2401 2402 # Yield the data. 2403 if return_id: 2404 yield spin, spin_id 2405 else: 2406 yield spin
2407 2408
2409 -def residue_loop(selection=None, pipe=None, full_info=False, return_id=False):
2410 """Generator function for looping over all the residues of the given selection. 2411 2412 @param selection: The residue selection identifier. 2413 @type selection: str 2414 @param pipe: The data pipe containing the residue. Defaults to the current data pipe. 2415 @type pipe: str 2416 @param full_info: A flag specifying if the amount of information to be returned. If false, only the data container is returned. If true, the molecule name, residue number, and residue name is additionally returned. 2417 @type full_info: boolean 2418 @keyword return_id: A flag which if True will cause the molecule identification string of the molecule spin to be returned in addition to the spin container. 2419 @type return_id: bool 2420 @return: The residue specific data container and, if full_info=True, the molecule name. 2421 @rtype: instance of the ResidueContainer class. If full_info=True, the type is the tuple (ResidueContainer, str). 2422 """ 2423 2424 # The data pipe. 2425 if pipe == None: 2426 pipe = pipes.cdp_name() 2427 2428 # Test the data pipe. 2429 pipes.test(pipe) 2430 2431 # Get the data pipe. 2432 dp = pipes.get_pipe(pipe) 2433 2434 # Test for the presence of data, and end the execution of this function if there is none. 2435 if not exists_mol_res_spin_data(pipe=pipe): 2436 return 2437 2438 # Parse the selection string. 2439 select_obj = Selection(selection) 2440 2441 # Loop over the molecules. 2442 for mol in dp.mol: 2443 # Loop over the residues. 2444 for res in mol.res: 2445 # Skip the residue if there is no match to the selection. 2446 if not select_obj.contains_res(res_num=res.num, res_name=res.name, mol=mol.name): 2447 continue 2448 2449 # Generate the spin id. 2450 if return_id: 2451 res_id = generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_num=res.num, res_name=res.name) 2452 2453 # Yield the residue data container. 2454 if full_info and return_id: 2455 yield res, mol.name, res_id 2456 elif full_info: 2457 yield res, mol.name 2458 elif return_id: 2459 yield res, res_id 2460 else: 2461 yield res
2462 2463
2464 -def return_molecule(selection=None, pipe=None):
2465 """Function for returning the molecule data container of the given selection. 2466 2467 @param selection: The molecule selection identifier. 2468 @type selection: str 2469 @param pipe: The data pipe containing the molecule. Defaults to the current data pipe. 2470 @type pipe: str 2471 @return: The molecule specific data container. 2472 @rtype: instance of the MoleculeContainer class. 2473 """ 2474 2475 # The data pipe. 2476 if pipe == None: 2477 pipe = pipes.cdp_name() 2478 2479 # Test the data pipe. 2480 pipes.test(pipe) 2481 2482 # Get the data pipe. 2483 dp = pipes.get_pipe(pipe) 2484 2485 # Parse the selection string. 2486 select_obj = Selection(selection) 2487 2488 # Loop over the molecules. 2489 mol_num = 0 2490 mol_container = None 2491 for mol in dp.mol: 2492 # Skip the molecule if there is no match to the selection. 2493 if not select_obj.contains_mol(mol=mol.name): 2494 continue 2495 2496 # Skip named molecules if the selection is None. 2497 if selection == None and mol.name != None: 2498 continue 2499 2500 # Store the molecule container. 2501 mol_container = mol 2502 2503 # Increment the molecule number counter. 2504 mol_num = mol_num + 1 2505 2506 # No unique identifier. 2507 if mol_num > 1: 2508 raise RelaxMultiMolIDError(selection) 2509 2510 # Return the molecule container. 2511 return mol_container
2512 2513
2514 -def return_molecule_by_name(pipe_cont=None, pipe_name=None, mol_name=None):
2515 """Return the molecule container matching the given name. 2516 2517 @keyword pipe_cont: The data pipe object. 2518 @type pipe_cont: PipeContainer instance 2519 @keyword pipe_name: The data pipe name. 2520 @type pipe_name: str 2521 @keyword mol_name: The molecule name. If not supplied and only a single molecule container exists, then that container will be returned. 2522 @type mol_name: str 2523 @return: The molecule container object. 2524 @rtype: MoleculeContainer instance 2525 """ 2526 2527 # The data pipe. 2528 if pipe_cont == None: 2529 pipe_cont = pipes.get_pipe(pipe) 2530 2531 # No molecule name specified, so assume a single molecule. 2532 if mol_name == None: 2533 # More than one molecule. 2534 if len(pipe_cont.mol) > 1: 2535 raise RelaxError("Cannot return the molecule with no name as more than one molecule exists.") 2536 2537 # Return the molecule. 2538 return pipe_cont.mol[0] 2539 2540 # Loop over the molecules. 2541 for mol in pipe_cont.mol: 2542 # Return the matching molecule. 2543 if mol.name == mol_name: 2544 return mol
2545 2546
2547 -def return_residue(selection=None, pipe=None, indices=False):
2548 """Function for returning the residue data container of the given selection. 2549 2550 @param selection: The residue selection identifier. 2551 @type selection: str 2552 @param pipe: The data pipe containing the residue. Defaults to the current data pipe. 2553 @type pipe: str 2554 @return: The residue specific data container, and the molecule and residue indices if asked. 2555 @rtype: instance of the ResidueContainer class. 2556 """ 2557 2558 # The data pipe. 2559 if pipe == None: 2560 pipe = pipes.cdp_name() 2561 2562 # Test the data pipe. 2563 pipes.test(pipe) 2564 2565 # Get the data pipe. 2566 dp = pipes.get_pipe(pipe) 2567 2568 # Parse the selection string. 2569 select_obj = Selection(selection) 2570 2571 # Loop over the molecules. 2572 res = None 2573 res_num = 0 2574 res_container = None 2575 for i in range(len(dp.mol)): 2576 # Skip the molecule if there is no match to the selection. 2577 if not select_obj.contains_mol(mol=dp.mol[i].name): 2578 continue 2579 2580 # Store the molecule index. 2581 mol_index = i 2582 2583 # Loop over the residues. 2584 for j in range(len(dp.mol[i].res)): 2585 # Skip the residue if there is no match to the selection. 2586 if not select_obj.contains_res(res_num=dp.mol[i].res[j].num, res_name=dp.mol[i].res[j].name, mol=dp.mol[i].name): 2587 continue 2588 2589 # Store the residue container and index. 2590 res_container = dp.mol[i].res[j] 2591 res_index = j 2592 2593 # Increment the residue number counter. 2594 res_num = res_num + 1 2595 2596 # No unique identifier. 2597 if res_num > 1: 2598 raise RelaxMultiResIDError(selection) 2599 2600 # Return the residue container. 2601 if indices: 2602 return res_container, mol_index, res_index 2603 else: 2604 return res_container
2605 2606
2607 -def return_residue_by_info(mol=None, res_name=None, res_num=None):
2608 """Return the residue container matching the given name. 2609 2610 @keyword mol: The molecule container. 2611 @type mol: MoleculeContainer instance 2612 @keyword res_name: The residue name. If not supplied and only a single residue container exists, then that container will be returned. 2613 @type res_name: str 2614 @keyword res_num: The residue number. If not supplied and only a single residue container exists, then that container will be returned. 2615 @type res_num: str 2616 @return: The residue container object. 2617 @rtype: ResidueContainer instance 2618 """ 2619 2620 # No residue name or number specified, so assume a single residue. 2621 if res_name == None and res_num == None: 2622 # More than one residue. 2623 if len(mol.res) > 1: 2624 raise RelaxError("Cannot return the residue with no name or number as more than one residue exists.") 2625 2626 # Return the residue. 2627 return mol.res[0] 2628 2629 # Loop over the residues. 2630 for res in mol.res: 2631 # Return the matching residue. 2632 if res_name != None and res_num != None: 2633 if res.name == res_name and res.num == res_num: 2634 return res 2635 elif res_name != None: 2636 if res.name == res_name: 2637 return res 2638 elif res_num != None: 2639 if res.num == res_num: 2640 return res
2641 2642
2643 -def return_spin(spin_id=None, pipe=None, full_info=False, multi=False):
2644 """Return the spin data container corresponding to the given spin ID string. 2645 2646 @keyword spin_id: The unique spin ID string. 2647 @type spin_id: str 2648 @keyword pipe: The data pipe containing the spin. Defaults to the current data pipe. 2649 @type pipe: str 2650 @keyword full_info: A flag specifying if the amount of information to be returned. If false, only the data container is returned. If true, the molecule name, residue number, and residue name is additionally returned. 2651 @type full_info: bool 2652 @keyword multi: A flag which if True will allow multiple spins to be returned. 2653 @type multi: bool 2654 @return: The spin system specific data container and, if full_info=True, the molecule name, residue number, and residue name. 2655 @rtype: SpinContainer instance of list of instances or tuple of (str, int, str, SpinContainer instance or list of instances) 2656 """ 2657 2658 # The data pipe. 2659 if pipe == None: 2660 pipe = pipes.cdp_name() 2661 2662 # Get the data pipe. 2663 dp = pipes.get_pipe(pipe) 2664 2665 # No spin ID, so assume there is no spin. 2666 if spin_id not in dp.mol._spin_id_lookup: 2667 return None 2668 2669 # The indices from the look up table. 2670 else: 2671 mol_index, res_index, spin_index = dp.mol._spin_id_lookup[spin_id] 2672 2673 # Return the data. 2674 if full_info and multi: 2675 return [dp.mol[mol_index].name], [dp.mol[mol_index].res[res_index].num], [dp.mol[mol_index].res[res_index].name], [dp.mol[mol_index].res[res_index].spin[spin_index]] 2676 elif full_info: 2677 return dp.mol[mol_index].name, dp.mol[mol_index].res[res_index].num, dp.mol[mol_index].res[res_index].name, dp.mol[mol_index].res[res_index].spin[spin_index] 2678 elif multi: 2679 return [dp.mol[mol_index].res[res_index].spin[spin_index]] 2680 else: 2681 return dp.mol[mol_index].res[res_index].spin[spin_index]
2682 2683
2684 -def return_spin_by_info(res=None, spin_name=None, spin_num=None):
2685 """Return the spin container matching the given name. 2686 2687 @keyword res: The residue container. 2688 @type res: ResidueContainer instance 2689 @keyword spin_name: The spin name. If not supplied and only a single spin container exists, then that container will be returned. 2690 @type spin_name: str 2691 @keyword spin_num: The spin number. If not supplied and only a single spin container exists, then that container will be returned. 2692 @type spin_num: str 2693 @return: The spin container object. 2694 @rtype: SpinContainer instance 2695 """ 2696 2697 # No spin name or number specified, so assume a single spin. 2698 if spin_name == None and spin_num == None: 2699 # More than one spin. 2700 if len(res.spin) > 1: 2701 raise RelaxError("Cannot return the spin with no name or number as more than one spin exists.") 2702 2703 # Return the spin. 2704 return res.spin[0] 2705 2706 # Loop over the spins. 2707 for spin in res.spin: 2708 # Return the matching spin. 2709 if spin_name != None and spin_num != None: 2710 if spin.name == spin_name and spin.num == spin_num: 2711 return spin 2712 elif spin_name != None: 2713 if spin.name == spin_name: 2714 return spin 2715 elif spin_num != None: 2716 if spin.num == spin_num: 2717 return spin
2718 2719
2720 -def return_spin_from_selection(selection=None, pipe=None, full_info=False, multi=False):
2721 """Function for returning the spin data container of the given selection. 2722 2723 If more than one selection is given, then the boolean AND operation will be used to pull out the spin. 2724 2725 2726 @keyword selection: The spin selection identifier. 2727 @type selection: str 2728 @keyword pipe: The data pipe containing the spin. Defaults to the current data pipe. 2729 @type pipe: str 2730 @keyword full_info: A flag specifying if the amount of information to be returned. If false, only the data container is returned. If true, the molecule name, residue number, and residue name is additionally returned. 2731 @type full_info: bool 2732 @keyword multi: A flag which if True will allow multiple spins to be returned. 2733 @type multi: bool 2734 @return: The spin system specific data container and, if full_info=True, the molecule name, residue number, and residue name. 2735 @rtype: SpinContainer instance of list of instances or tuple of (str, int, str, SpinContainer instance or list of instances) 2736 """ 2737 2738 # Handle Unicode. 2739 if is_unicode(selection): 2740 selection = str(selection) 2741 2742 # The data pipe. 2743 if pipe == None: 2744 pipe = pipes.cdp_name() 2745 2746 # Get the data pipe. 2747 dp = pipes.get_pipe(pipe) 2748 2749 # Parse the selection string. 2750 select_obj = Selection(selection) 2751 2752 # Loop over the molecules. 2753 spin_num = 0 2754 spins = [] 2755 mol_names = [] 2756 res_nums = [] 2757 res_names = [] 2758 spin_ids = [] 2759 for mol in dp.mol: 2760 # Skip the molecule if there is no match to the selection. 2761 if not select_obj.contains_mol(mol=mol.name): 2762 continue 2763 2764 # Loop over the residues. 2765 for res in mol.res: 2766 # Skip the residue if there is no match to the selection. 2767 if not select_obj.contains_res(res_num=res.num, res_name=res.name, mol=mol.name): 2768 continue 2769 2770 # Loop over the spins. 2771 for spin in res.spin: 2772 # Skip the spin if there is no match to the selection. 2773 if not select_obj.contains_spin(spin_num=spin.num, spin_name=spin.name, res_num=res.num, res_name=res.name, mol=mol.name): 2774 continue 2775 2776 # Store all data. 2777 mol_names.append(mol.name) 2778 res_nums.append(res.num) 2779 res_names.append(res.name) 2780 spins.append(spin) 2781 2782 # Increment the spin number counter. 2783 spin_num = spin_num + 1 2784 2785 # Generate as store the spin ID. 2786 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_num=res.num, res_name=res.name, spin_num=spin.num, spin_name=spin.name)) 2787 2788 # No unique identifier. 2789 if not multi and spin_num > 1: 2790 raise RelaxMultiSpinIDError(selection, spin_ids) 2791 2792 # Return the spin container. 2793 if full_info and multi: 2794 return mol_names, res_nums, res_names, spins 2795 elif full_info: 2796 return mol_names[0], res_nums[0], res_names[0], spins[0] 2797 elif multi: 2798 return spins 2799 elif len(spins): 2800 return spins[0] 2801 else: 2802 return None
2803 2804
2805 -def return_spin_from_index(global_index=None, pipe=None, return_spin_id=False):
2806 """Function for returning the spin data container corresponding to the global index. 2807 2808 @param global_index: The global spin index, spanning the molecule and residue containers. 2809 @type global_index: int 2810 @param pipe: The data pipe containing the spin. Defaults to the current data pipe. 2811 @type pipe: str 2812 @keyword return_spin_id: A flag which if True will cause both the spin container and spin identification string to be returned. 2813 @type return_spin_id: bool 2814 @return: The spin specific data container (additionally the spin identification string if return_spin_id is set). 2815 @rtype: instance of the SpinContainer class (or tuple of SpinContainer and str) 2816 """ 2817 2818 # The data pipe. 2819 if pipe == None: 2820 pipe = pipes.cdp_name() 2821 2822 # Test the data pipe. 2823 pipes.test(pipe) 2824 2825 # Loop over the spins. 2826 spin_num = 0 2827 for spin, mol_name, res_num, res_name in spin_loop(full_info=True, pipe=pipe): 2828 # Match to the global index. 2829 if spin_num == global_index: 2830 # Return the spin and the spin_id string. 2831 if return_spin_id: 2832 # The spin identification string. 2833 spin_id = generate_spin_id(pipe_name=pipe, mol_name=mol_name, res_num=res_num, res_name=res_name, spin_num=spin.num, spin_name=spin.name) 2834 2835 # Return both objects. 2836 return spin, spin_id 2837 2838 # Return the spin by itself. 2839 else: 2840 return spin 2841 2842 # Increment the spin number. 2843 spin_num = spin_num + 1
2844 2845
2846 -def return_spin_indices(spin_id=None, pipe=None):
2847 """Return the molecule, residue and spin indices corresponding to the given spin ID string. 2848 2849 @keyword spin_id: The unique spin ID string. 2850 @type spin_id: str 2851 @param pipe: The data pipe containing the spin. Defaults to the current data pipe. 2852 @type pipe: str 2853 @return: The molecule, residue and spin indices. 2854 @rtype: list of int 2855 """ 2856 2857 # The data pipe. 2858 if pipe == None: 2859 pipe = pipes.cdp_name() 2860 2861 # Get the data pipe. 2862 dp = pipes.get_pipe(pipe) 2863 2864 # No spin ID, so switch to selection matching. 2865 if spin_id not in dp.mol._spin_id_lookup: 2866 # Parse the selection string. 2867 select_obj = Selection(spin_id) 2868 2869 # Loop over the molecules. 2870 for i in range(len(dp.mol)): 2871 # Skip the molecule if there is no match to the selection. 2872 if not select_obj.contains_mol(mol=dp.mol[i].name): 2873 continue 2874 2875 # The molecule index. 2876 mol_index = i 2877 2878 # Loop over the residues. 2879 for j in range(len(dp.mol[i].res)): 2880 # Skip the residue if there is no match to the selection. 2881 if not select_obj.contains_res(res_num=dp.mol[i].res[j].num, res_name=dp.mol[i].res[j].name, mol=dp.mol[i].name): 2882 continue 2883 2884 # The residue index. 2885 res_index = j 2886 2887 # Loop over the spins. 2888 for k in range(len(dp.mol[i].res[j].spin)): 2889 # Skip the spin if there is no match to the selection. 2890 if not select_obj.contains_spin(spin_num=dp.mol[i].res[j].spin[k].num, spin_name=dp.mol[i].res[j].spin[k].name, res_num=dp.mol[i].res[j].num, res_name=dp.mol[i].res[j].name, mol=dp.mol[i].name): 2891 continue 2892 2893 # The spin index. 2894 spin_index = k 2895 2896 # Found the spin, so terminate. 2897 break 2898 2899 # The indices from the look up table. 2900 else: 2901 mol_index, res_index, spin_index = dp.mol._spin_id_lookup[spin_id] 2902 2903 # Return the data. 2904 return mol_index, res_index, spin_index
2905 2906
2907 -def return_single_molecule_info(molecule_token):
2908 """Return the single molecule name corresponding to the molecule token. 2909 2910 @param molecule_token: The molecule identification string. 2911 @type molecule_token: str 2912 @return: The molecule name. 2913 @rtype: str 2914 """ 2915 2916 # Parse the molecule token for renaming and renumbering. 2917 molecule_info = parse_token(molecule_token) 2918 2919 # Determine the molecule name. 2920 mol_name = None 2921 for info in molecule_info: 2922 # A molecule name identifier. 2923 if mol_name == None: 2924 mol_name = info 2925 else: 2926 raise RelaxError("The molecule identifier " + repr(molecule_token) + " does not correspond to a single molecule.") 2927 2928 # Convert to a string if needed. 2929 if mol_name != None and not isinstance(mol_name, str): 2930 mol_name = str(mol_name) 2931 2932 # Return the molecule name. 2933 return mol_name
2934 2935
2936 -def return_single_residue_info(residue_token):
2937 """Return the single residue number and name corresponding to the residue token. 2938 2939 @param residue_token: The residue identification string. 2940 @type residue_token: str 2941 @return: A tuple containing the residue number and the residue name. 2942 @rtype: (int, str) 2943 """ 2944 2945 # Parse the residue token for renaming and renumbering. 2946 residue_info = parse_token(residue_token) 2947 2948 # Determine the residue number and name. 2949 res_num = None 2950 res_name = None 2951 for info in residue_info: 2952 # A residue name identifier. 2953 if isinstance(info, str): 2954 if res_name == None: 2955 res_name = info 2956 else: 2957 raise RelaxError("The residue identifier " + repr(residue_token) + " does not correspond to a single residue.") 2958 2959 # A residue number identifier. 2960 if isinstance(info, int): 2961 if res_num == None: 2962 res_num = info 2963 else: 2964 raise RelaxError("The residue identifier " + repr(residue_token) + " does not correspond to a single residue.") 2965 2966 # Return the residue number and name. 2967 return res_num, res_name
2968 2969
2970 -def return_single_spin_info(spin_token):
2971 """Return the single spin number and name corresponding to the spin token. 2972 2973 @param spin_token: The spin identification string. 2974 @type spin_token: str 2975 @return: A tuple containing the spin number and the spin name. 2976 @rtype: (int, str) 2977 """ 2978 2979 # Parse the spin token for renaming and renumbering. 2980 spin_info = parse_token(spin_token) 2981 2982 # Determine the spin number and name. 2983 spin_num = None 2984 spin_name = None 2985 for info in spin_info: 2986 # A spin name identifier. 2987 if isinstance(info, str): 2988 if spin_name == None: 2989 spin_name = info 2990 else: 2991 raise RelaxError("The spin identifier " + repr(spin_token) + " does not correspond to a single spin.") 2992 2993 # A spin number identifier. 2994 if isinstance(info, int): 2995 if spin_num == None: 2996 spin_num = info 2997 else: 2998 raise RelaxError("The spin identifier " + repr(spin_token) + " does not correspond to a single spin.") 2999 3000 # Return the spin number and name. 3001 return spin_num, spin_name
3002 3003
3004 -def same_sequence(pipe1, pipe2):
3005 """Test if the sequence data in both pipes are the same. 3006 3007 @param pipe1: The first data pipe. 3008 @type pipe1: str 3009 @param pipe2: The second data pipe. 3010 @type pipe2: str 3011 @return: True if the sequence data matches, False otherwise. 3012 @rtype: bool 3013 """ 3014 3015 # Test the data pipes. 3016 pipes.test(pipe1) 3017 pipes.test(pipe2) 3018 3019 # Get the data pipes. 3020 pipe1 = pipes.get_pipe(pipe1) 3021 pipe2 = pipes.get_pipe(pipe2) 3022 3023 # Different number of molecules. 3024 if len(pipe1.mol) != len(pipe2.mol): 3025 return False 3026 3027 # Loop over the molecules. 3028 for i in range(len(pipe1.mol)): 3029 # Different number of residues. 3030 if len(pipe1.mol[i].res) != len(pipe2.mol[i].res): 3031 return False 3032 3033 # Loop over the residues. 3034 for j in range(len(pipe1.mol[i].res)): 3035 # Different number of spins. 3036 if len(pipe1.mol[i].res[j].spin) != len(pipe2.mol[i].res[j].spin): 3037 return False 3038 3039 # Loop over the spins. 3040 for k in range(len(pipe1.mol[i].res[j].spin)): 3041 # Different spin numbers. 3042 if pipe1.mol[i].res[j].spin[k].num != pipe2.mol[i].res[j].spin[k].num: 3043 return False 3044 3045 # Different spin names. 3046 if pipe1.mol[i].res[j].spin[k].name != pipe2.mol[i].res[j].spin[k].name: 3047 return False 3048 3049 # The sequence is the same. 3050 return True
3051 3052
3053 -def set_spin_element(spin_id=None, element=None, pipe=None, force=False):
3054 """Set the element type of the spins. 3055 3056 @keyword spin_id: The spin identification string. 3057 @type spin_id: str 3058 @keyword element: The IUPAC element name. 3059 @type element: str 3060 @param pipe: The data pipe to operate on. Defaults to the current data pipe. 3061 @type pipe: str 3062 @keyword force: A flag which if True will cause the element to be changed. 3063 @type force: bool 3064 """ 3065 3066 # Valid names (for NMR active spins). 3067 valid_names = ['H', 3068 'C', 3069 'N', 3070 'O', 3071 'F', 3072 'Na', 3073 'P', 3074 'Cd' 3075 ] 3076 3077 # Check. 3078 if element not in valid_names: 3079 raise RelaxError("The element name '%s' is not valid and should be one of the IUPAC names %s." % (element, valid_names)) 3080 3081 # The data pipe. 3082 if pipe == None: 3083 pipe = pipes.cdp_name() 3084 3085 # Test the data pipe. 3086 pipes.test(pipe) 3087 3088 # Set the element name for the matching spins. 3089 for spin, id in spin_loop(spin_id, pipe=pipe, return_id=True): 3090 if hasattr(spin, 'element') and spin.element and not force: 3091 warn(RelaxWarning("The element type of the spin '%s' is already set. Set the force flag to True to rename." % id)) 3092 else: 3093 spin.element = element
3094 3095
3096 -def set_spin_isotope(spin_id=None, isotope=None, pipe=None, force=False):
3097 """Set the nuclear isotope type of the spins. 3098 3099 @keyword spin_id: The spin identification string. 3100 @type spin_id: str 3101 @keyword isotope: The nuclear isotope type. 3102 @type isotope: str 3103 @param pipe: The data pipe to operate on. Defaults to the current data pipe. 3104 @type pipe: str 3105 @keyword force: A flag which if True will cause the isotope type to be changed. If None, then the warning messages will not mention the need to change this flag to rename. 3106 @type force: bool or None 3107 """ 3108 3109 # Types currently supported in relax. 3110 supported_types = [ 3111 '1H', 3112 '2H', 3113 '13C', 3114 '14N', 3115 '15N', 3116 '17O', 3117 '19F', 3118 '23Na', 3119 '31P', 3120 '113Cd' 3121 ] 3122 3123 # Check. 3124 if isotope not in supported_types: 3125 raise RelaxError("The nuclear isotope type '%s' is currently not supported." % isotope) 3126 3127 # The data pipe. 3128 if pipe == None: 3129 pipe = pipes.cdp_name() 3130 3131 # Test the data pipe. 3132 pipes.test(pipe) 3133 3134 # Set the isotope type for the matching spins. 3135 for spin, id in spin_loop(spin_id, pipe=pipe, return_id=True): 3136 if hasattr(spin, 'isotope') and spin.isotope and force != True: 3137 if force == False: 3138 warn(RelaxWarning("The nuclear isotope type of the spin '%s' is already set. Change the force flag to True to reset." % id)) 3139 else: 3140 warn(RelaxWarning("The nuclear isotope type of the spin '%s' is already set." % id)) 3141 else: 3142 spin.isotope = isotope
3143 3144
3145 -def spin_id_variants(dp=None, mol_index=None, res_index=None, spin_index=None):
3146 """Generate a list of spin ID variants for the given set of molecule, residue and spin indices. 3147 3148 @keyword dp: The data pipe to work on. 3149 @type dp: PipeContainer instance 3150 @keyword mol_index: The molecule index. 3151 @type mol_index: int 3152 @keyword res_index: The residue index. 3153 @type res_index: int 3154 @keyword spin_index: The spin index. 3155 @type spin_index: int 3156 @return: The list of all spin IDs matching the spin. 3157 @rtype: list of str 3158 """ 3159 3160 # Initialise. 3161 spin_ids = [] 3162 mol = dp.mol[mol_index] 3163 res = dp.mol[mol_index].res[res_index] 3164 spin = dp.mol[mol_index].res[res_index].spin[spin_index] 3165 mol_count = len(dp.mol) 3166 res_count = len(mol.res) 3167 spin_count = len(res.spin) 3168 3169 # Unique top level info. 3170 unique_top_level_res_name = True 3171 unique_top_level_res_num = True 3172 unique_top_level_spin_name = True 3173 unique_top_level_spin_num = True 3174 if res.name != None and dp.mol._res_name_count[res.name] > 1: 3175 unique_top_level_res_name = False 3176 if res.num != None and dp.mol._res_num_count[res.num] > 1: 3177 unique_top_level_res_num = False 3178 if spin.name != None and dp.mol._spin_name_count[spin.name] > 1: 3179 unique_top_level_spin_name = False 3180 if spin.num != None and dp.mol._spin_num_count[spin.num] > 1: 3181 unique_top_level_spin_num = False 3182 3183 # Unique molecule level info. 3184 unique_mol_level_res_name = True 3185 unique_mol_level_res_num = True 3186 unique_mol_level_spin_name = True 3187 unique_mol_level_spin_num = True 3188 if res.name != None and mol._res_name_count[res.name] > 1: 3189 unique_mol_level_res_name = False 3190 if res.num != None and mol._res_num_count[res.num] > 1: 3191 unique_mol_level_res_num = False 3192 if spin.name != None and mol._spin_name_count[spin.name] > 1: 3193 unique_mol_level_spin_name = False 3194 if spin.num != None and mol._spin_num_count[spin.num] > 1: 3195 unique_mol_level_spin_num = False 3196 3197 # Unique residue level info. 3198 unique_res_level_spin_name = True 3199 unique_res_level_spin_num = True 3200 if spin.name != None and res._spin_name_count[spin.name] > 1: 3201 unique_res_level_spin_name = False 3202 if spin.num != None and res._spin_num_count[spin.num] > 1: 3203 unique_res_level_spin_num = False 3204 3205 # IDs with the molecule name. 3206 if mol.name != None: 3207 # IDs with the residue name. 3208 if res.name != None: 3209 # The molecule name, residue name and spin name. 3210 if spin.name != None and unique_mol_level_res_name and unique_res_level_spin_name: 3211 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_name=res.name, spin_name=spin.name)) 3212 3213 # The molecule name, residue name and spin number. 3214 if spin.num != None and unique_mol_level_res_name and unique_res_level_spin_num: 3215 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_name=res.name, spin_num=spin.num)) 3216 3217 # The molecule name and residue name. 3218 if spin_count == 1 and unique_mol_level_res_name: 3219 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_name=res.name)) 3220 3221 # IDs with the residue number. 3222 if res.num != None: 3223 # The molecule name, residue number and spin name. 3224 if spin.name != None and unique_mol_level_res_num and unique_res_level_spin_name: 3225 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_num=res.num, spin_name=spin.name)) 3226 3227 # The molecule name, residue number and spin number. 3228 if spin.num != None and unique_mol_level_res_num and unique_res_level_spin_num: 3229 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_num=res.num, spin_num=spin.num)) 3230 3231 # The molecule name and residue number. 3232 if spin_count == 1 and unique_mol_level_res_num: 3233 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_num=res.num)) 3234 3235 # The molecule name and spin name. 3236 if spin.name != None and unique_mol_level_spin_name: 3237 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, spin_name=spin.name)) 3238 3239 # The molecule name and spin number. 3240 if spin.num != None and unique_mol_level_spin_num: 3241 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, spin_num=spin.num)) 3242 3243 # The molecule name. 3244 if spin_count == 1 and res_count == 1: 3245 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name)) 3246 3247 # IDs with the residue name. 3248 if res.name != None: 3249 # The residue name and spin name. 3250 if spin.name != None and unique_top_level_res_name and unique_res_level_spin_name: 3251 spin_ids.append(generate_spin_id(pipe_cont=dp, res_name=res.name, spin_name=spin.name)) 3252 3253 # The residue name and spin number. 3254 if spin.num != None and unique_top_level_res_name and unique_res_level_spin_num: 3255 spin_ids.append(generate_spin_id(pipe_cont=dp, res_name=res.name, spin_num=spin.num)) 3256 3257 # The residue name. 3258 if spin_count == 1 and unique_top_level_res_name: 3259 spin_ids.append(generate_spin_id(pipe_cont=dp, res_name=res.name)) 3260 3261 # IDs with the residue number. 3262 if res.num != None: 3263 # The residue number and spin name. 3264 if spin.name != None and unique_top_level_res_num and unique_res_level_spin_name: 3265 spin_ids.append(generate_spin_id(pipe_cont=dp, res_num=res.num, spin_name=spin.name)) 3266 3267 # The residue number and spin number. 3268 if spin.num != None and unique_top_level_res_num and unique_res_level_spin_num: 3269 spin_ids.append(generate_spin_id(pipe_cont=dp, res_num=res.num, spin_num=spin.num)) 3270 3271 # The residue number. 3272 if spin_count == 1 and unique_top_level_res_num: 3273 spin_ids.append(generate_spin_id(pipe_cont=dp, res_num=res.num)) 3274 3275 # The spin name. 3276 if spin.name != None and unique_top_level_spin_name: 3277 spin_ids.append(generate_spin_id(pipe_cont=dp, spin_name=spin.name)) 3278 3279 # The spin number. 3280 if spin.num != None and unique_top_level_spin_num: 3281 spin_ids.append(generate_spin_id(pipe_cont=dp, spin_num=spin.num)) 3282 3283 # Return the IDs. 3284 return spin_ids
3285 3286
3287 -def spin_id_variants_cleanup(dp=None, mol_index=None, res_index=None, spin_index=None):
3288 """Generate a list of spin ID variants to eliminate for the given set of molecule, residue and spin indices. 3289 3290 @keyword dp: The data pipe to work on. 3291 @type dp: PipeContainer instance 3292 @keyword mol_index: The molecule index. 3293 @type mol_index: int 3294 @keyword res_index: The residue index. 3295 @type res_index: int 3296 @keyword spin_index: The spin index. 3297 @type spin_index: int 3298 @return: The list of all spin IDs matching the spin. 3299 @rtype: list of str 3300 """ 3301 3302 # Initialise. 3303 spin_ids = [] 3304 mol = dp.mol[mol_index] 3305 res = dp.mol[mol_index].res[res_index] 3306 spin = dp.mol[mol_index].res[res_index].spin[spin_index] 3307 mol_count = len(dp.mol) 3308 res_count = len(mol.res) 3309 spin_count = len(res.spin) 3310 3311 # Unique top level info. 3312 unique_top_level_res_name = True 3313 unique_top_level_res_num = True 3314 unique_top_level_spin_name = True 3315 unique_top_level_spin_num = True 3316 if res.name != None and dp.mol._res_name_count[res.name] > 1: 3317 unique_top_level_res_name = False 3318 if res.num != None and dp.mol._res_num_count[res.num] > 1: 3319 unique_top_level_res_num = False 3320 if spin.name != None and dp.mol._spin_name_count[spin.name] > 1: 3321 unique_top_level_spin_name = False 3322 if spin.num != None and dp.mol._spin_num_count[spin.num] > 1: 3323 unique_top_level_spin_num = False 3324 3325 # Unique molecule level info. 3326 unique_mol_level_res_name = True 3327 unique_mol_level_res_num = True 3328 unique_mol_level_spin_name = True 3329 unique_mol_level_spin_num = True 3330 if res.name != None and mol._res_name_count[res.name] > 1: 3331 unique_mol_level_res_name = False 3332 if res.num != None and mol._res_num_count[res.num] > 1: 3333 unique_mol_level_res_num = False 3334 if spin.name != None and mol._spin_name_count[spin.name] > 1: 3335 unique_mol_level_spin_name = False 3336 if spin.num != None and mol._spin_num_count[spin.num] > 1: 3337 unique_mol_level_spin_num = False 3338 3339 # Unique residue level info. 3340 unique_res_level_spin_name = True 3341 unique_res_level_spin_num = True 3342 if spin.name != None and res._spin_name_count[spin.name] > 1: 3343 unique_res_level_spin_name = False 3344 if spin.num != None and res._spin_num_count[spin.num] > 1: 3345 unique_res_level_spin_num = False 3346 3347 # IDs with the molecule name. 3348 if mol.name != None: 3349 # IDs with the residue name. 3350 if res.name != None: 3351 # The molecule name, residue name and spin name. 3352 if spin.name != None and (not unique_mol_level_res_name or not unique_res_level_spin_name): 3353 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_name=res.name, spin_name=spin.name)) 3354 3355 # The molecule name, residue name and spin number. 3356 if spin.num != None and (not unique_mol_level_res_name or not unique_res_level_spin_num): 3357 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_name=res.name, spin_num=spin.num)) 3358 3359 # The molecule name and residue name. 3360 if not unique_mol_level_res_name or spin_count > 1: 3361 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_name=res.name)) 3362 3363 # IDs with the residue number. 3364 if res.num != None: 3365 # The molecule name, residue number and spin name. 3366 if spin.name != None and (not unique_mol_level_res_num or not unique_res_level_spin_name): 3367 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_num=res.num, spin_name=spin.name)) 3368 3369 # The molecule name, residue number and spin number. 3370 if spin.num != None and (not unique_mol_level_res_num or not unique_res_level_spin_num): 3371 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_num=res.num, spin_num=spin.num)) 3372 3373 # The molecule name and residue number. 3374 if not unique_mol_level_res_num or spin_count > 1: 3375 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_num=res.num)) 3376 3377 # The molecule name and spin name. 3378 if spin.name != None and not unique_mol_level_spin_name: 3379 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, spin_name=spin.name)) 3380 3381 # The molecule name and spin number. 3382 if spin.num != None and not unique_mol_level_spin_num: 3383 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, spin_num=spin.num)) 3384 3385 # The molecule name. 3386 if res_count > 1 or spin_count > 1: 3387 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name)) 3388 3389 # IDs with the residue name. 3390 if res.name != None: 3391 # The residue name and spin name. 3392 if spin.name != None and (not unique_top_level_res_name and not unique_top_level_spin_name): 3393 spin_ids.append(generate_spin_id(pipe_cont=dp, res_name=res.name, spin_name=spin.name)) 3394 3395 # The residue name and spin number. 3396 if spin.num != None and (not unique_top_level_res_name and not unique_top_level_spin_num): 3397 spin_ids.append(generate_spin_id(pipe_cont=dp, res_name=res.name, spin_num=spin.num)) 3398 3399 # The residue name. 3400 if not unique_top_level_res_name or spin_count > 1: 3401 spin_ids.append(generate_spin_id(pipe_cont=dp, res_name=res.name)) 3402 3403 # IDs with the residue number. 3404 if res.num != None: 3405 # The residue number and spin name. 3406 if spin.name != None and (not unique_top_level_res_num and not unique_top_level_spin_name): 3407 spin_ids.append(generate_spin_id(pipe_cont=dp, res_num=res.num, spin_name=spin.name)) 3408 3409 # The residue number and spin number. 3410 if spin.num != None and (not unique_top_level_res_num and not unique_top_level_spin_num): 3411 spin_ids.append(generate_spin_id(pipe_cont=dp, res_num=res.num, spin_num=spin.num)) 3412 3413 # The residue number. 3414 if not unique_top_level_res_num or spin_count > 1: 3415 spin_ids.append(generate_spin_id(pipe_cont=dp, res_num=res.num)) 3416 3417 # The spin name. 3418 if spin.name != None and not unique_top_level_spin_name: 3419 spin_ids.append(generate_spin_id(pipe_cont=dp, spin_name=spin.name)) 3420 3421 # The spin number. 3422 if spin.num != None and not unique_top_level_spin_num: 3423 spin_ids.append(generate_spin_id(pipe_cont=dp, spin_num=spin.num)) 3424 3425 # Return the IDs. 3426 return spin_ids
3427 3428
3429 -def spin_id_variants_prune(dp=None, mol_index=None, res_index=None, spin_index=None):
3430 """Generate a list of spin ID variants to eliminate for the given set of molecule, residue and spin indices. 3431 3432 @keyword dp: The data pipe to work on. 3433 @type dp: PipeContainer instance 3434 @keyword mol_index: The molecule index. 3435 @type mol_index: int 3436 @keyword res_index: The residue index. 3437 @type res_index: int 3438 @keyword spin_index: The spin index. 3439 @type spin_index: int 3440 @return: The list of all spin IDs matching the spin. 3441 @rtype: list of str 3442 """ 3443 3444 # Initialise. 3445 spin_ids = [] 3446 mol = dp.mol[mol_index] 3447 res = dp.mol[mol_index].res[res_index] 3448 spin = dp.mol[mol_index].res[res_index].spin[spin_index] 3449 mol_count = len(dp.mol) 3450 res_count = len(mol.res) 3451 spin_count = len(res.spin) 3452 3453 # IDs with the molecule name. 3454 if mol.name != None: 3455 # IDs with the residue name. 3456 if res.name != None: 3457 # The molecule name, residue name and spin name. 3458 if spin.name != None: 3459 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_name=res.name, spin_name=spin.name)) 3460 3461 # The molecule name, residue name and spin number. 3462 if spin.num != None: 3463 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_name=res.name, spin_num=spin.num)) 3464 3465 # The molecule name and residue name. 3466 if spin_count == 1: 3467 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_name=res.name)) 3468 3469 # IDs with the residue number. 3470 if res.num != None: 3471 # The molecule name, residue number and spin name. 3472 if spin.name != None: 3473 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_num=res.num, spin_name=spin.name)) 3474 3475 # The molecule name, residue number and spin number. 3476 if spin.num != None: 3477 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_num=res.num, spin_num=spin.num)) 3478 3479 # The molecule name and residue number. 3480 if spin_count == 1: 3481 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_num=res.num)) 3482 3483 # The molecule name and spin name. 3484 if spin.name != None and res_count == 1: 3485 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, spin_name=spin.name)) 3486 3487 # The molecule name and spin number. 3488 if spin.num != None and res_count == 1: 3489 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, spin_num=spin.num)) 3490 3491 # The molecule name. 3492 if res_count == 1 and spin_count == 1: 3493 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name)) 3494 3495 # IDs with the residue name. 3496 if res.name != None: 3497 # The residue name and spin name. 3498 if spin.name != None and mol_count == 1: 3499 spin_ids.append(generate_spin_id(pipe_cont=dp, res_name=res.name, spin_name=spin.name)) 3500 3501 # The residue name and spin number. 3502 if spin.num != None and mol_count == 1: 3503 spin_ids.append(generate_spin_id(pipe_cont=dp, res_name=res.name, spin_num=spin.num)) 3504 3505 # The residue name. 3506 if mol_count == 1 and spin_count == 1: 3507 spin_ids.append(generate_spin_id(pipe_cont=dp, res_name=res.name)) 3508 3509 # IDs with the residue number. 3510 if res.num != None: 3511 # The residue number and spin name. 3512 if spin.name != None and mol_count == 1: 3513 spin_ids.append(generate_spin_id(pipe_cont=dp, res_num=res.num, spin_name=spin.name)) 3514 3515 # The residue number and spin number. 3516 if spin.num != None and mol_count == 1: 3517 spin_ids.append(generate_spin_id(pipe_cont=dp, res_num=res.num, spin_num=spin.num)) 3518 3519 # The residue number. 3520 if mol_count == 1 and spin_count == 1: 3521 spin_ids.append(generate_spin_id(pipe_cont=dp, res_num=res.num)) 3522 3523 # The spin name. 3524 if spin.name != None and mol_count == 1 and res_count == 1: 3525 spin_ids.append(generate_spin_id(pipe_cont=dp, spin_name=spin.name)) 3526 3527 # The spin number. 3528 if spin.num != None and mol_count == 1 and res_count == 1: 3529 spin_ids.append(generate_spin_id(pipe_cont=dp, spin_num=spin.num)) 3530 3531 # Return the IDs. 3532 return spin_ids
3533 3534
3535 -def spin_index_loop(selection=None, pipe=None):
3536 """Generator function for looping over all selected spins, returning the mol-res-spin indices. 3537 3538 @param selection: The spin system selection identifier. 3539 @type selection: str 3540 @param pipe: The data pipe containing the spin. Defaults to the current data pipe. 3541 @type pipe: str 3542 @return: The molecule, residue, and spin index. 3543 @rtype: tuple of 3 int 3544 """ 3545 3546 # The data pipe. 3547 if pipe == None: 3548 pipe = pipes.cdp_name() 3549 3550 # Test the data pipe. 3551 pipes.test(pipe) 3552 3553 # Get the data pipe. 3554 dp = pipes.get_pipe(pipe) 3555 3556 # Test for the presence of data, and end the execution of this function if there is none. 3557 if not exists_mol_res_spin_data(pipe=pipe): 3558 return 3559 3560 # Parse the selection string. 3561 select_obj = Selection(selection) 3562 3563 # Loop over the molecules. 3564 for mol_index in range(len(dp.mol)): 3565 # Alias the molecule container. 3566 mol = dp.mol[mol_index] 3567 3568 # Loop over the residues. 3569 for res_index in range(len(dp.mol[mol_index].res)): 3570 # Alias the residue container. 3571 res = dp.mol[mol_index].res[res_index] 3572 3573 # Loop over the spins. 3574 for spin_index in range(len(dp.mol[mol_index].res[res_index].spin)): 3575 # Alias the spin container. 3576 spin = dp.mol[mol_index].res[res_index].spin[spin_index] 3577 3578 # Skip the spin if there is no match to the selection. 3579 if not select_obj.contains_spin(spin_num=spin.num, spin_name=spin.name, res_num=res.num, res_name=res.name, mol=mol.name): 3580 continue 3581 3582 # Yield the spin system specific indices. 3583 yield mol_index, res_index, spin_index
3584 3585
3586 -def spin_loop(selection=None, pipe=None, full_info=False, return_id=False, skip_desel=False):
3587 """Generator function for looping over all the spin systems of the given selection. 3588 3589 @keyword selection: The spin system selection identifier. 3590 @type selection: str 3591 @keyword pipe: The data pipe containing the spin. Defaults to the current data pipe. 3592 @type pipe: str 3593 @keyword full_info: A flag which if True will cause the the molecule name, residue number, and residue name to be returned in addition to the spin container. 3594 @type full_info: bool 3595 @keyword return_id: A flag which if True will cause the spin identification string of the current spin to be returned in addition to the spin container. 3596 @type return_id: bool 3597 @keyword skip_desel: A flag which if True will cause deselected spins to be skipped. 3598 @type skip_desel: bool 3599 @return: The spin system specific data container. If full_info is True, a tuple of the spin container, the molecule name, residue number, and residue name. If return_id is True, a tuple of the spin container and spin id. If both flags are True, then a tuple of the spin container, the molecule name, residue number, residue name, and spin id. 3600 @rtype: If full_info and return_id are False, SpinContainer instance. If full_info is True and return_id is false, a tuple of (SpinContainer instance, str, int, str). If full_info is False and return_id is True, a tuple of (SpinContainer instance, str). If full_info and return_id are False, a tuple of (SpinContainer instance, str, int, str, str) 3601 """ 3602 3603 # The data pipe. 3604 if pipe == None: 3605 pipe = pipes.cdp_name() 3606 3607 # Test the data pipe. 3608 pipes.test(pipe) 3609 3610 # Get the data pipe. 3611 dp = pipes.get_pipe(pipe) 3612 3613 # Test for the presence of data, and end the execution of this function if there is none. 3614 if not exists_mol_res_spin_data(pipe=pipe): 3615 return 3616 3617 # Parse the selection string. 3618 select_obj = Selection(selection) 3619 3620 # Loop over the molecules. 3621 for mol in dp.mol: 3622 # Loop over the residues. 3623 for res in mol.res: 3624 # Loop over the spins. 3625 for spin in res.spin: 3626 # Skip the spin if there is no match to the selection. 3627 if not select_obj.contains_spin(spin_num=spin.num, spin_name=spin.name, res_num=res.num, res_name=res.name, mol=mol.name): 3628 continue 3629 3630 # Skip deselected spins. 3631 if skip_desel and not spin.select: 3632 continue 3633 3634 # Generate the spin id. 3635 if return_id: 3636 spin_id = generate_spin_id_unique(pipe_cont=dp, mol=mol, res=res, spin=spin) 3637 3638 # Yield the data. 3639 if full_info and return_id: 3640 yield spin, mol.name, res.num, res.name, spin_id 3641 elif full_info: 3642 yield spin, mol.name, res.num, res.name 3643 elif return_id: 3644 yield spin, spin_id 3645 else: 3646 yield spin
3647 3648
3649 -def type_molecule(mol_id, type=None, force=False):
3650 """Set the molecule type. 3651 3652 @param mol_id: The molecule identification string. 3653 @type mol_id: str 3654 @param type: The molecule type. 3655 @type type: str 3656 @keyword force: A flag which if True will cause the molecule type to be overwritten. 3657 @type force: bool 3658 """ 3659 3660 # Check the type. 3661 if type not in ALLOWED_MOL_TYPES: 3662 raise RelaxError("The molecule type '%s' must be one of %s." % (type, ALLOWED_MOL_TYPES)) 3663 3664 # Disallow residue and spin selections. 3665 select_obj = Selection(mol_id) 3666 if select_obj.has_residues(): 3667 raise RelaxResSelectDisallowError 3668 if select_obj.has_spins(): 3669 raise RelaxSpinSelectDisallowError 3670 3671 # Change the molecule types. 3672 for mol in molecule_loop(mol_id): 3673 if hasattr(mol, 'type') and mol.type and not force: 3674 warn(RelaxWarning("The molecule '%s' already has its type set. Set the force flag to change." % mol_id)) 3675 else: 3676 mol.type = type
3677