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 # Update all metadata. 971 metadata_update() 972 973 # Release the lock. 974 finally: 975 status.spin_lock.release(sys._getframe().f_code.co_name)
976 977
978 -def delete_residue(res_id=None):
979 """Function for deleting residues from the current data pipe. 980 981 @param res_id: The molecule and residue identifier string. 982 @type res_id: str 983 """ 984 985 # Acquire the spin lock (data modifying function), and make sure it is finally released. 986 status.spin_lock.acquire(sys._getframe().f_code.co_name) 987 try: 988 # Split up the selection string. 989 mol_token, res_token, spin_token = tokenise(res_id) 990 991 # Disallow spin selections. 992 if spin_token != None: 993 raise RelaxSpinSelectDisallowError 994 995 # Parse the tokens. 996 residues = parse_token(res_token) 997 998 # Molecule loop. 999 for mol in molecule_loop(res_id): 1000 # List of indices to delete. 1001 indices = [] 1002 1003 # Loop over the residues of the molecule. 1004 for i in range(len(mol.res)): 1005 # Remove the residue is there is a match. 1006 if mol.res[i].num in residues or mol.res[i].name in residues: 1007 indices.append(i) 1008 1009 # Reverse the indices. 1010 indices.reverse() 1011 1012 # First prune the metadata. 1013 for index in indices: 1014 metadata_prune(mol_index=mol._mol_index, res_index=index) 1015 1016 # Delete the residues. 1017 for index in indices: 1018 mol.res.pop(index) 1019 1020 # Create an empty residue container if no residues remain. 1021 if len(mol.res) == 0: 1022 mol.res.add_item() 1023 1024 # Update all metadata. 1025 metadata_update() 1026 1027 # Release the lock. 1028 finally: 1029 status.spin_lock.release(sys._getframe().f_code.co_name)
1030 1031
1032 -def delete_spin(spin_id=None):
1033 """Function for deleting spins from the current data pipe. 1034 1035 @param spin_id: The molecule, residue, and spin identifier string. 1036 @type spin_id: str 1037 """ 1038 1039 # Acquire the spin lock (data modifying function), and make sure it is finally released. 1040 status.spin_lock.acquire(sys._getframe().f_code.co_name) 1041 try: 1042 1043 # Split up the selection string. 1044 mol_token, res_token, spin_token = tokenise(spin_id) 1045 1046 # Parse the tokens. 1047 spins = parse_token(spin_token) 1048 1049 # Residue loop. 1050 for res in residue_loop(spin_id): 1051 # List of indices to delete. 1052 indices = [] 1053 1054 # Loop over the spins of the residue. 1055 for i in range(len(res.spin)): 1056 # Store the spin indices for deletion. 1057 if res.spin[i].num in spins or res.spin[i].name in spins: 1058 indices.append(i) 1059 1060 # Reverse the indices. 1061 indices.reverse() 1062 1063 # First prune the metadata. 1064 for index in indices: 1065 metadata_prune(mol_index=res._mol_index, res_index=res._res_index, spin_index=index) 1066 1067 # Delete the spins. 1068 for index in indices: 1069 res.spin.pop(index) 1070 1071 # Create an empty spin container if no spins remain. 1072 if len(res.spin) == 0: 1073 res.spin.add_item() 1074 1075 # Update all metadata. 1076 metadata_update() 1077 1078 # Release the lock. 1079 finally: 1080 status.spin_lock.release(sys._getframe().f_code.co_name)
1081 1082
1083 -def display_molecule(mol_id=None):
1084 """Function for displaying the information associated with the molecule. 1085 1086 @param mol_id: The molecule identifier string. 1087 @type mol_id: str 1088 """ 1089 1090 # Split up the selection string. 1091 mol_token, res_token, spin_token = tokenise(mol_id) 1092 1093 # Disallowed selections. 1094 if res_token != None: 1095 raise RelaxResSelectDisallowError 1096 if spin_token != None: 1097 raise RelaxSpinSelectDisallowError 1098 1099 # The molecule selection string. 1100 if mol_token: 1101 mol_sel = '#' + mol_token 1102 else: 1103 mol_sel = None 1104 1105 # Print a header. 1106 print("\n\n%-15s %-15s" % ("Molecule", "Number of residues")) 1107 1108 # Molecule loop. 1109 for mol in molecule_loop(mol_sel): 1110 # Print the molecule data. 1111 print("%-15s %-15s" % (mol.name, repr(len(mol.res))))
1112 1113
1114 -def display_residue(res_id=None):
1115 """Function for displaying the information associated with the residue. 1116 1117 @param res_id: The molecule and residue identifier string. 1118 @type res_id: str 1119 """ 1120 1121 # Split up the selection string. 1122 mol_token, res_token, spin_token = tokenise(res_id) 1123 1124 # Disallow spin selections. 1125 if spin_token != None: 1126 raise RelaxSpinSelectDisallowError 1127 1128 # Print a header. 1129 print("\n\n%-15s %-15s %-15s %-15s" % ("Molecule", "Res number", "Res name", "Number of spins")) 1130 1131 # Residue loop. 1132 for res, mol_name in residue_loop(res_id, full_info=True): 1133 print("%-15s %-15s %-15s %-15s" % (mol_name, repr(res.num), res.name, repr(len(res.spin))))
1134 1135
1136 -def display_spin(spin_id=None):
1137 """Function for displaying the information associated with the spin. 1138 1139 @param spin_id: The molecule and residue identifier string. 1140 @type spin_id: str 1141 """ 1142 1143 # Print a header. 1144 print("\n\n%-15s %-15s %-15s %-15s %-15s" % ("Molecule", "Res number", "Res name", "Spin number", "Spin name")) 1145 1146 # Spin loop. 1147 for spin, mol_name, res_num, res_name in spin_loop(spin_id, full_info=True): 1148 # Print the residue data. 1149 print("%-15s %-15s %-15s %-15s %-15s" % (mol_name, repr(res_num), res_name, repr(spin.num), spin.name))
1150 1151
1152 -def exists_mol_res_spin_data(pipe=None):
1153 """Function for determining if any molecule-residue-spin data exists. 1154 1155 @keyword pipe: The data pipe in which the molecule-residue-spin data will be checked for. 1156 @type pipe: str 1157 @return: The answer to the question about the existence of data. 1158 @rtype: bool 1159 """ 1160 1161 # The current data pipe. 1162 if pipe == None: 1163 pipe = pipes.cdp_name() 1164 1165 # Test the data pipe. 1166 pipes.test(pipe) 1167 1168 # Get the data pipe. 1169 dp = pipes.get_pipe(pipe) 1170 1171 # The molecule, residue, spin object stack is empty. 1172 if dp.mol.is_empty(): 1173 return False 1174 1175 # Otherwise. 1176 return True
1177 1178
1179 -def find_index(selection=None, pipe=None, global_index=True):
1180 """Find and return the spin index or indices for the selection string. 1181 1182 @keyword selection: The spin selection identifier. 1183 @type selection: str 1184 @keyword pipe: The data pipe containing the spin. Defaults to the current data pipe. 1185 @type pipe: str 1186 @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. 1187 @type global_index: bool 1188 @return: The global spin index or the molecule, residue, and spin indices. 1189 @rtype: int or tuple of 3 int 1190 """ 1191 1192 # The data pipe. 1193 if pipe == None: 1194 pipe = pipes.cdp_name() 1195 1196 # Test the data pipe. 1197 pipes.test(pipe) 1198 1199 # Get the data pipe. 1200 dp = pipes.get_pipe(pipe) 1201 1202 # Parse the selection string. 1203 select_obj = Selection(selection) 1204 1205 # Init the mol and global index. 1206 global_i = -1 1207 mol_index = -1 1208 1209 # Loop over the molecules. 1210 for mol in dp.mol: 1211 # Increment the molecule index. 1212 mol_index = mol_index + 1 1213 1214 # Init the residue index. 1215 res_index = -1 1216 1217 # Loop over the residues. 1218 for res in mol.res: 1219 # Increment the residue index. 1220 res_index = res_index + 1 1221 1222 # Init the residue index. 1223 spin_index = -1 1224 1225 # Loop over the spins. 1226 for spin in res.spin: 1227 # Increment the spin and global index. 1228 spin_index = spin_index + 1 1229 global_i = global_i + 1 1230 1231 # Stop if the spin matches the selection. 1232 if select_obj.contains_spin(spin_num=spin.num, spin_name=spin.name, res_num=res.num, res_name=res.name, mol=mol.name): 1233 # Return the indices. 1234 if global_index: 1235 return global_i 1236 else: 1237 return mol_index, res_index, spin_index
1238 1239
1240 -def first_residue_num(selection=None):
1241 """Determine the first residue number. 1242 1243 @return: The number of the first residue. 1244 @rtype: int 1245 """ 1246 1247 # Get the molecule. 1248 mol = return_molecule(selection) 1249 1250 # The first residue number. 1251 return mol.res[0].num
1252 1253
1254 -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):
1255 """Generate the spin selection string. 1256 1257 @keyword pipe_cont: The data pipe object. 1258 @type pipe_cont: PipeContainer instance 1259 @keyword pipe_name: The data pipe name. 1260 @type pipe_name: str 1261 @keyword mol_name: The molecule name. 1262 @type mol_name: str or None 1263 @keyword res_num: The residue number. 1264 @type res_num: int or None 1265 @keyword res_name: The residue name. 1266 @type res_name: str or None 1267 @keyword spin_num: The spin number. 1268 @type spin_num: int or None 1269 @keyword spin_name: The spin name. 1270 @type spin_name: str or None 1271 @return: The spin identification string. 1272 @rtype: str 1273 """ 1274 1275 # The data pipe. 1276 if pipe_cont == None: 1277 pipe_cont = pipes.get_pipe(pipe_name) 1278 1279 # Init. 1280 id = "" 1281 1282 # Molecule name and container. 1283 if mol_name != None: 1284 id = id + "#" + mol_name 1285 1286 # Residue data. 1287 res_num_id = '' 1288 res_name_id = '' 1289 if res_num != None: 1290 res_num_id = id + ":" + str(res_num) 1291 res_num_exists = res_num_id in pipe_cont.mol._spin_id_lookup 1292 if res_name != None: 1293 res_name_id = id + ":" + res_name 1294 res_name_exists = res_name_id in pipe_cont.mol._spin_id_lookup 1295 1296 # Select between the name and number, defaulting to the residue number if needed. 1297 if res_name != None and res_num != None: 1298 if res_num_exists and res_name_exists: 1299 id = res_num_id 1300 elif not res_num_exists or not res_name_exists: 1301 id = res_num_id 1302 elif res_num_exists: 1303 id = res_num_id 1304 elif res_name_exists: 1305 id = res_name_id 1306 elif res_num != None: 1307 id = res_num_id 1308 elif res_name != None: 1309 id = res_name_id 1310 elif res_num != None: 1311 id = res_num_id 1312 elif res_name != None: 1313 id = res_name_id 1314 1315 # Spin data. 1316 spin_num_id = '' 1317 spin_name_id = '' 1318 spin_num_exists = False 1319 spin_name_exists = False 1320 if spin_num != None: 1321 spin_num_id = id + "@" + str(spin_num) 1322 spin_num_exists = spin_num_id in pipe_cont.mol._spin_id_lookup 1323 if spin_name != None: 1324 spin_name_id = id + "@" + spin_name 1325 spin_name_exists = spin_name_id in pipe_cont.mol._spin_id_lookup 1326 1327 # Select between the name and number, defaulting to the spin name if needed. 1328 if spin_name != None and spin_num != None: 1329 if spin_num_exists and spin_name_exists: 1330 id = spin_name_id 1331 elif not spin_num_exists or not spin_name_exists: 1332 id = spin_name_id 1333 elif spin_name_exists: 1334 id = spin_name_id 1335 elif spin_num_exists: 1336 id = spin_num_id 1337 elif spin_name != None: 1338 id = spin_name_id 1339 elif spin_num != None: 1340 id = spin_num_id 1341 elif spin_name != None: 1342 id = spin_name_id 1343 elif spin_num != None: 1344 id = spin_num_id 1345 1346 # Return the full spin ID string. 1347 return id
1348 1349
1350 -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):
1351 """Generate the spin selection string from the given data array. 1352 1353 @param data: An array containing the molecule, residue, and/or spin data. 1354 @type data: list of str 1355 @param mol_name_col: The column containing the molecule name information. 1356 @type mol_name_col: int or None 1357 @param res_name_col: The column containing the residue name information. 1358 @type res_name_col: int or None 1359 @param res_num_col: The column containing the residue number information. 1360 @type res_num_col: int or None 1361 @param spin_name_col: The column containing the spin name information. 1362 @type spin_name_col: int or None 1363 @param spin_num_col: The column containing the spin number information. 1364 @type spin_num_col: int or None 1365 @return: The spin identification string. 1366 @rtype: str 1367 """ 1368 1369 # Init. 1370 id = "" 1371 1372 # Molecule data. 1373 if mol_name_col and data[mol_name_col-1] not in [None, 'None']: 1374 id = id + "#" + data[mol_name_col-1] 1375 1376 # Residue data. 1377 if res_num_col and data[res_num_col-1] not in [None, 'None']: 1378 id = id + ":" + str(data[res_num_col-1]) 1379 elif res_name_col and data[res_name_col-1] not in [None, 'None']: 1380 id = id + ":" + data[res_name_col-1] 1381 1382 # Spin data. 1383 if spin_num_col and data[spin_num_col-1] not in [None, 'None']: 1384 id = id + "@" + str(data[spin_num_col-1]) 1385 elif spin_name_col and data[spin_name_col-1] not in [None, 'None']: 1386 id = id + "@" + data[spin_name_col-1] 1387 1388 # Return the spin id string. 1389 return id
1390 1391
1392 -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):
1393 """Generate a list of spin ID variants for the given set of molecule, residue and spin indices. 1394 1395 @keyword pipe_cont: The data pipe object. 1396 @type pipe_cont: PipeContainer instance 1397 @keyword pipe_name: The data pipe name. 1398 @type pipe_name: str 1399 @keyword mol: The molecule container. 1400 @type mol: MoleculeContainer instance 1401 @keyword res: The residue container. 1402 @type res: ResidueContainer instance 1403 @keyword spin: The spin container. 1404 @type spin: SpinContainer instance 1405 @keyword mol_name: The molecule name (an alternative to the molecule container). 1406 @type mol_name: str or None 1407 @keyword res_num: The residue number (an alternative to the residue container). 1408 @type res_num: int or None 1409 @keyword res_name: The residue name (an alternative to the residue container). 1410 @type res_name: str or None 1411 @keyword spin_num: The spin number (an alternative to the spin container). 1412 @type spin_num: int or None 1413 @keyword spin_name: The spin name (an alternative to the spin container). 1414 @type spin_name: str or None 1415 @return: The unique spin ID. 1416 @rtype: str 1417 """ 1418 1419 # The data pipe. 1420 if pipe_cont == None: 1421 pipe_cont = pipes.get_pipe(pipe_name) 1422 1423 # Get the containers if needed. 1424 if mol == None: 1425 mol = return_molecule_by_name(pipe_cont=pipe_cont, mol_name=mol_name) 1426 if mol != None and res == None: 1427 if res_name != None or res_num != None: 1428 res = return_residue_by_info(mol=mol, res_name=res_name, res_num=res_num) 1429 elif len(mol.res) == 1: 1430 res = mol.res[0] 1431 if res != None and spin == None: 1432 if spin_name != None or spin_num != None: 1433 spin = return_spin_by_info(res=res, spin_name=spin_name, spin_num=spin_num) 1434 elif len(res.spin) == 1: 1435 spin = res.spin[0] 1436 1437 # The info. 1438 if mol: 1439 mol_name = mol.name 1440 if res: 1441 res_name = res.name 1442 res_num = res.num 1443 if spin: 1444 spin_name = spin.name 1445 spin_num = spin.num 1446 1447 # Unique info. 1448 unique_res_name = True 1449 if res and res.name != None and mol._res_name_count[res.name] > 1: 1450 unique_res_name = False 1451 unique_res_num = True 1452 if res and res.num != None and mol._res_num_count[res.num] > 1: 1453 unique_res_num = False 1454 unique_spin_name = True 1455 if spin and spin.name != None and res._spin_name_count[spin.name] > 1: 1456 unique_spin_name = False 1457 unique_spin_num = True 1458 if spin and spin.num != None and res._spin_num_count[spin.num] > 1: 1459 unique_spin_num = False 1460 1461 # The unique ID. 1462 if unique_res_num and unique_spin_name: 1463 return generate_spin_id(pipe_cont=pipe_cont, mol_name=mol_name, res_num=res_num, spin_name=spin_name) 1464 if unique_res_num and unique_spin_num: 1465 return generate_spin_id(pipe_cont=pipe_cont, mol_name=mol_name, res_num=res_num, spin_num=spin_num) 1466 if unique_res_name and unique_spin_num: 1467 return generate_spin_id(pipe_cont=pipe_cont, mol_name=mol_name, res_name=res_name, spin_num=spin_num) 1468 if unique_res_name and unique_spin_name: 1469 return generate_spin_id(pipe_cont=pipe_cont, mol_name=mol_name, res_name=res_name, spin_name=spin_name)
1470 1471
1472 -def get_molecule_ids(selection=None):
1473 """Return a list of the molecule ID strings. 1474 1475 @param selection: The molecule selection identifier. 1476 @type selection: str 1477 @return: The molecule ID strings. 1478 @rtype: list of str 1479 """ 1480 1481 # No data pipes, so return an empty list without throwing an error. 1482 if not pipes.cdp_name(): 1483 return [] 1484 1485 # Loop over the molecules, append the ID of each within the selection. 1486 mol_ids = [] 1487 for mol, mol_id in molecule_loop(selection, return_id=True): 1488 mol_ids.append(mol_id) 1489 1490 # Return the IDs. 1491 return mol_ids
1492 1493
1494 -def get_molecule_names(selection=None):
1495 """Return a list of the molecule names. 1496 1497 @param selection: The molecule selection identifier. 1498 @type selection: str 1499 @return: The molecule names. 1500 @rtype: list of str 1501 """ 1502 1503 # No data pipes, so return an empty list without throwing an error. 1504 if not pipes.cdp_name(): 1505 return [] 1506 1507 # Loop over the molecules, append the name of each within the selection. 1508 mol_names = [] 1509 for mol in molecule_loop(selection): 1510 mol_names.append(mol.name) 1511 1512 # Return the names. 1513 return mol_names
1514 1515
1516 -def get_residue_ids(selection=None):
1517 """Return a list of the residue ID strings. 1518 1519 @param selection: The molecule and residue selection identifier. 1520 @type selection: str 1521 @return: The residue ID strings. 1522 @rtype: list of str 1523 """ 1524 1525 # No data pipes, so return an empty list without throwing an error. 1526 if not pipes.cdp_name(): 1527 return [] 1528 1529 # Loop over the residues, appending the ID of each within the selection. 1530 res_ids = [] 1531 for res, res_id in residue_loop(selection, return_id=True): 1532 res_ids.append(res_id) 1533 1534 # Return the IDs. 1535 return res_ids
1536 1537
1538 -def get_residue_names(selection=None):
1539 """Return a list of the residue names. 1540 1541 @param selection: The molecule and residue selection identifier. 1542 @type selection: str 1543 @return: The residue names. 1544 @rtype: list of str 1545 """ 1546 1547 # No data pipes, so return an empty list without throwing an error. 1548 if not pipes.cdp_name(): 1549 return [] 1550 1551 # Loop over the residues, appending the name of each within the selection. 1552 res_names = [] 1553 for res in residue_loop(selection): 1554 res_names.append(res.name) 1555 1556 # Return the names. 1557 return res_names
1558 1559
1560 -def get_residue_nums(selection=None):
1561 """Return a list of the residue numbers. 1562 1563 @param selection: The molecule and residue selection identifier. 1564 @type selection: str 1565 @return: The residue numbers. 1566 @rtype: list of str 1567 """ 1568 1569 # No data pipes, so return an empty list without throwing an error. 1570 if not pipes.cdp_name(): 1571 return [] 1572 1573 # Loop over the residues, appending the number of each within the selection. 1574 res_nums = [] 1575 for res in residue_loop(selection): 1576 res_nums.append(res.num) 1577 1578 # Return the numbers. 1579 return res_nums
1580 1581
1582 -def get_spin_ids(selection=None):
1583 """Return a list of the spin ID strings. 1584 1585 @param selection: The molecule and spin selection identifier. 1586 @type selection: str 1587 @return: The spin ID strings. 1588 @rtype: list of str 1589 """ 1590 1591 # No data pipes, so return an empty list without throwing an error. 1592 if not pipes.cdp_name(): 1593 return [] 1594 1595 # Loop over the spins, appending the ID of each within the selection. 1596 spin_ids = [] 1597 for spin, spin_id in spin_loop(selection, return_id=True): 1598 spin_ids.append(spin_id) 1599 1600 # Return the IDs. 1601 return spin_ids
1602 1603
1604 -def is_pseudoatom(spin=None):
1605 """Check if the given spin container corresponds to a pseudo-atom. 1606 1607 @keyword spin: The spin container to check. 1608 @type spin: SpinContainer instance 1609 @return: True if this is a pseudo-atom, False otherwise. 1610 @rtype: bool 1611 """ 1612 1613 # Check for the 'members' data structure. 1614 if hasattr(spin, 'members'): 1615 return True 1616 1617 # Normal atom. 1618 return False
1619 1620
1621 -def index_molecule(mol_name=None, pipe=None):
1622 """Return the index of the molecule of the given name. 1623 1624 @keyword mol_name: The name of the molecule. 1625 @type mol_name: str or None 1626 @keyword pipe: The data pipe, defaulting to the current data pipe. 1627 @type pipe: str or None 1628 @return: The index of the molecule, if it exists. 1629 @rtype: int or None 1630 """ 1631 1632 # The data pipe. 1633 if pipe == None: 1634 pipe = pipes.cdp_name() 1635 1636 # Test the data pipe. 1637 pipes.test(pipe) 1638 1639 # Get the data pipe. 1640 dp = pipes.get_pipe(pipe) 1641 1642 # Single molecule and no name given. 1643 if mol_name == None and len(dp.mol) == 1: 1644 return 0 1645 1646 # Loop over the molecules. 1647 i = 0 1648 for mol in dp.mol: 1649 # A match. 1650 if mol.name == mol_name: 1651 return i 1652 1653 # Increment the index. 1654 i += 1 1655 1656 # Nothing found. 1657 return None
1658 1659
1660 -def index_residue(res_num=None, res_name=None, mol_index=None, pipe=None):
1661 """Return the index of the residue. 1662 1663 @keyword res_num: The number of the residue. 1664 @type res_num: int 1665 @keyword res_name: The name of the residue. 1666 @type res_name: str 1667 @keyword mol_index: The index of the molecule. 1668 @type mol_index: str 1669 @keyword pipe: The data pipe, defaulting to the current data pipe. 1670 @type pipe: str or None 1671 @return: The index of the residue, if it exists. 1672 @rtype: int or None 1673 """ 1674 1675 # The data pipe. 1676 if pipe == None: 1677 pipe = pipes.cdp_name() 1678 1679 # Test the data pipe. 1680 pipes.test(pipe) 1681 1682 # Get the data pipe. 1683 dp = pipes.get_pipe(pipe) 1684 1685 # Single unnamed residue. 1686 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: 1687 return 0 1688 1689 # Loop over the residues. 1690 i = 0 1691 for res in dp.mol[mol_index].res: 1692 # A unique number match. 1693 if res_num != None and res.num == res_num: 1694 return i 1695 1696 # Match names, if no number is given. 1697 if res_num == None and res_name != None and res.name == res_name: 1698 return i 1699 1700 # Increment the index. 1701 i += 1 1702 1703 # Nothing found. 1704 return None
1705 1706
1707 -def last_residue_num(selection=None):
1708 """Determine the last residue number. 1709 1710 @param selection: The molecule selection identifier. 1711 @type selection: str 1712 @return: The number of the last residue. 1713 @rtype: int 1714 """ 1715 1716 # Get the molecule. 1717 mol = return_molecule(selection) 1718 1719 # The last residue number. 1720 return mol.res[-1].num
1721 1722
1723 -def linear_ave(positions):
1724 """Perform linear averaging of the atomic positions. 1725 1726 @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. 1727 @type positions: list of lists of numpy float arrays 1728 @return: The averaged positions as a list of vectors. 1729 @rtype: list of numpy float arrays 1730 """ 1731 1732 # Loop over the multiple models. 1733 ave = [] 1734 for model_index in range(len(positions[0])): 1735 # Append an empty vector. 1736 ave.append(array([0.0, 0.0, 0.0])) 1737 1738 # Loop over the x, y, and z coordinates. 1739 for coord_index in range(3): 1740 # Loop over the atomic positions. 1741 for atom_index in range(len(positions)): 1742 ave[model_index][coord_index] = ave[model_index][coord_index] + positions[atom_index][model_index][coord_index] 1743 1744 # Average. 1745 ave[model_index][coord_index] = ave[model_index][coord_index] / len(positions) 1746 1747 # Return the averaged positions. 1748 return ave
1749 1750
1751 -def metadata_cleanup(mol_index=None, res_index=None, spin_index=None, pipe=None):
1752 """Prune all of the metadata matching the given indices. 1753 1754 @keyword mol_index: The index of the molecule to prune. If not supplied, all molecules will be pruned. 1755 @type mol_index: int or None 1756 @keyword res_index: The index of the residue to prune. If not supplied, all residues of the matching molecules will be pruned. 1757 @type res_index: int or None 1758 @keyword spin_index: The index of the spin to prune. If not supplied, all spins of the matching residues will be pruned. 1759 @type spin_index: int or None 1760 @keyword pipe: The data pipe to update, defaulting to the current data pipe. 1761 @type pipe: str or None 1762 """ 1763 1764 # The data pipe. 1765 if pipe == None: 1766 pipe = pipes.cdp_name() 1767 1768 # Test the data pipe. 1769 pipes.test(pipe) 1770 1771 # Get the data pipe. 1772 dp = pipes.get_pipe(pipe) 1773 1774 # Update the metadata info counts. 1775 metadata_counts(pipe_cont=dp) 1776 1777 # Loop over the molecules. 1778 to_remove = [] 1779 for i in range(len(dp.mol)): 1780 # Molecule skipping. 1781 if mol_index != None and mol_index != i: 1782 continue 1783 1784 # Alias. 1785 mol = dp.mol[i] 1786 1787 # Loop over the residues. 1788 for j in range(len(mol.res)): 1789 # Residue skipping. 1790 if res_index != None and res_index != j: 1791 continue 1792 1793 # Alias. 1794 res = mol.res[j] 1795 1796 # Loop over the spins. 1797 for k in range(len(res.spin)): 1798 # Spin skipping. 1799 if spin_index != None and spin_index != k: 1800 continue 1801 1802 # Alias. 1803 spin = res.spin[k] 1804 1805 # The list of IDs to remove. 1806 to_remove = spin_id_variants_cleanup(dp=dp, mol_index=i, res_index=j, spin_index=k) 1807 1808 # ID removal. 1809 for spin_id in to_remove: 1810 # Blank IDs. 1811 if spin_id == '': 1812 continue 1813 1814 # Remove from the list in the spin container itself. 1815 if spin_id in spin._spin_ids: 1816 spin._spin_ids.pop(spin._spin_ids.index(spin_id)) 1817 1818 # Remove the IDs from the look up table. 1819 if spin_id in dp.mol._spin_id_lookup: 1820 dp.mol._spin_id_lookup.pop(spin_id)
1821 1822
1823 -def metadata_counts(pipe_cont=None):
1824 """Update the molecule, residue, and spin name and number count metadata. 1825 1826 @keyword pipe_cont: The data pipe object. 1827 @type pipe_cont: PipeContainer instance 1828 """ 1829 1830 # The top level counts. 1831 pipe_cont.mol._res_name_count = {} 1832 pipe_cont.mol._res_num_count = {} 1833 pipe_cont.mol._spin_name_count = {} 1834 pipe_cont.mol._spin_num_count = {} 1835 1836 # Pre-parse: Update the metadata for determining if names and numbers already exist. 1837 for i in range(len(pipe_cont.mol)): 1838 # Alias. 1839 mol = pipe_cont.mol[i] 1840 1841 # The molecule level counts. 1842 mol._res_name_count = {} 1843 mol._res_num_count = {} 1844 mol._spin_name_count = {} 1845 mol._spin_num_count = {} 1846 1847 # Loop over the residues. 1848 for j in range(len(mol.res)): 1849 # Alias. 1850 res = mol.res[j] 1851 1852 # Count the residue names. 1853 if res.name != None: 1854 # Top level. 1855 if res.name not in pipe_cont.mol._res_name_count: 1856 pipe_cont.mol._res_name_count[res.name] = 1 1857 else: 1858 pipe_cont.mol._res_name_count[res.name] += 1 1859 1860 # Molecule level. 1861 if res.name not in mol._res_name_count: 1862 mol._res_name_count[res.name] = 1 1863 else: 1864 mol._res_name_count[res.name] += 1 1865 1866 # Count the residue numbers. 1867 if res.num != None: 1868 # Top level. 1869 if res.num not in pipe_cont.mol._res_num_count: 1870 pipe_cont.mol._res_num_count[res.num] = 1 1871 else: 1872 pipe_cont.mol._res_num_count[res.num] += 1 1873 1874 # Molecule level. 1875 if res.num not in mol._res_num_count: 1876 mol._res_num_count[res.num] = 1 1877 else: 1878 mol._res_num_count[res.num] += 1 1879 1880 # The residue level counts. 1881 res._spin_name_count = {} 1882 res._spin_num_count = {} 1883 1884 # Loop over the spins. 1885 for k in range(len(res.spin)): 1886 # Alias. 1887 spin = res.spin[k] 1888 1889 # Count the spin names. 1890 if spin.name != None: 1891 # Top level. 1892 if spin.name not in pipe_cont.mol._spin_name_count: 1893 pipe_cont.mol._spin_name_count[spin.name] = 1 1894 else: 1895 pipe_cont.mol._spin_name_count[spin.name] += 1 1896 1897 # Molecule level. 1898 if spin.name not in mol._spin_name_count: 1899 mol._spin_name_count[spin.name] = 1 1900 else: 1901 mol._spin_name_count[spin.name] += 1 1902 1903 # Residue level. 1904 if spin.name not in res._spin_name_count: 1905 res._spin_name_count[spin.name] = 1 1906 else: 1907 res._spin_name_count[spin.name] += 1 1908 1909 # Count the spin numbers. 1910 if spin.num != None: 1911 # Top level. 1912 if spin.num not in pipe_cont.mol._spin_num_count: 1913 pipe_cont.mol._spin_num_count[spin.num] = 1 1914 else: 1915 pipe_cont.mol._spin_num_count[spin.num] += 1 1916 1917 # Molecule level. 1918 if spin.num not in mol._spin_num_count: 1919 mol._spin_num_count[spin.num] = 1 1920 else: 1921 mol._spin_num_count[spin.num] += 1 1922 1923 # Residue level. 1924 if spin.num not in res._spin_num_count: 1925 res._spin_num_count[spin.num] = 1 1926 else: 1927 res._spin_num_count[spin.num] += 1
1928 1929
1930 -def metadata_prune(mol_index=None, res_index=None, spin_index=None, pipe=None):
1931 """Prune all of the metadata matching the given indices. 1932 1933 @keyword mol_index: The index of the molecule to prune. If not supplied, all molecules will be pruned. 1934 @type mol_index: int or None 1935 @keyword res_index: The index of the residue to prune. If not supplied, all residues of the matching molecules will be pruned. 1936 @type res_index: int or None 1937 @keyword spin_index: The index of the spin to prune. If not supplied, all spins of the matching residues will be pruned. 1938 @type spin_index: int or None 1939 @keyword pipe: The data pipe to update, defaulting to the current data pipe. 1940 @type pipe: str or None 1941 """ 1942 1943 # The data pipe. 1944 if pipe == None: 1945 pipe = pipes.cdp_name() 1946 1947 # Test the data pipe. 1948 pipes.test(pipe) 1949 1950 # Get the data pipe. 1951 dp = pipes.get_pipe(pipe) 1952 1953 # Update the metadata info counts. 1954 metadata_counts(pipe_cont=dp) 1955 1956 # Loop over the molecules. 1957 to_remove = [] 1958 for i in range(len(dp.mol)): 1959 # Molecule skipping. 1960 if mol_index != None and mol_index != i: 1961 continue 1962 1963 # Alias. 1964 mol = dp.mol[i] 1965 1966 # Loop over the residues. 1967 for j in range(len(mol.res)): 1968 # Residue skipping. 1969 if res_index != None and res_index != j: 1970 continue 1971 1972 # Alias. 1973 res = mol.res[j] 1974 1975 # Loop over the spins. 1976 for k in range(len(res.spin)): 1977 # Spin skipping. 1978 if spin_index != None and spin_index != k: 1979 continue 1980 1981 # Alias. 1982 spin = res.spin[k] 1983 1984 # The list of IDs to remove. 1985 to_remove = spin_id_variants_prune(dp=dp, mol_index=i, res_index=j, spin_index=k) 1986 1987 # ID removal. 1988 for spin_id in to_remove: 1989 # Blank IDs. 1990 if spin_id == '': 1991 continue 1992 1993 # Remove from the list in the spin container itself. 1994 if spin_id in spin._spin_ids: 1995 spin._spin_ids.pop(spin._spin_ids.index(spin_id)) 1996 1997 # Remove the IDs from the look up table. 1998 if spin_id in dp.mol._spin_id_lookup: 1999 dp.mol._spin_id_lookup.pop(spin_id)
2000 2001
2002 -def metadata_update(mol_index=None, res_index=None, spin_index=None, pipe=None):
2003 """Update all of the private look up metadata for the given containers. 2004 2005 @keyword mol_index: The index of the molecule to update. If not supplied, all molecules will be updated. 2006 @type mol_index: int or None 2007 @keyword res_index: The index of the residue to update. If not supplied, all residues will be updated. 2008 @type res_index: int or None 2009 @keyword spin_index: The index of the spin to update. If not supplied, all spins will be updated. 2010 @type spin_index: int or None 2011 @keyword pipe: The data pipe to update, defaulting to the current data pipe. 2012 @type pipe: str or None 2013 """ 2014 2015 # The data pipe. 2016 if pipe == None: 2017 pipe = pipes.cdp_name() 2018 2019 # Test the data pipe. 2020 pipes.test(pipe) 2021 2022 # Get the data pipe. 2023 dp = pipes.get_pipe(pipe) 2024 2025 # Update the metadata info counts. 2026 metadata_counts(pipe_cont=dp) 2027 2028 # Loop over the molecules. 2029 for i in range(len(dp.mol)): 2030 # Molecule skipping. 2031 if mol_index != None and mol_index != i: 2032 continue 2033 2034 # Alias. 2035 mol = dp.mol[i] 2036 2037 # Update the molecule metadata. 2038 mol._mol_index = i 2039 2040 # Loop over the residues. 2041 for j in range(len(mol.res)): 2042 # Residue skipping. 2043 if res_index != None and res_index != j: 2044 continue 2045 2046 # Alias. 2047 res = mol.res[j] 2048 2049 # Update the residue metadata. 2050 res._mol_name = mol.name 2051 res._mol_index = i 2052 res._res_index = j 2053 2054 # Loop over the spins. 2055 for k in range(len(res.spin)): 2056 # Spin skipping. 2057 if spin_index != None and spin_index != k: 2058 continue 2059 2060 # Alias. 2061 spin = res.spin[k] 2062 2063 # Update the spin metadata. 2064 spin._mol_name = mol.name 2065 spin._mol_index = i 2066 spin._res_name = res.name 2067 spin._res_num = res.num 2068 spin._res_index = j 2069 spin._spin_index = k 2070 2071 # The list of IDs to store. 2072 spin_ids = spin_id_variants(dp=dp, mol_index=i, res_index=j, spin_index=k) 2073 2074 # ID storage. 2075 spin._spin_ids = [] 2076 for spin_id in spin_ids: 2077 # Blank IDs. 2078 if spin_id == '': 2079 continue 2080 2081 # Store the list in the spin container itself. 2082 spin._spin_ids.append(spin_id) 2083 2084 # Update the look up table. 2085 dp.mol._spin_id_lookup[spin_id] = [i, j, k]
2086 2087
2088 -def molecule_loop(selection=None, pipe=None, return_id=False):
2089 """Generator function for looping over all the molecules of the given selection. 2090 2091 @param selection: The molecule selection identifier. 2092 @type selection: str 2093 @param pipe: The data pipe containing the molecule. Defaults to the current data pipe. 2094 @type pipe: str 2095 @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. 2096 @type return_id: bool 2097 @return: The molecule specific data container. 2098 @rtype: instance of the MoleculeContainer class. 2099 """ 2100 2101 # The data pipe. 2102 if pipe == None: 2103 pipe = pipes.cdp_name() 2104 2105 # Test the data pipe. 2106 pipes.test(pipe) 2107 2108 # Get the data pipe. 2109 dp = pipes.get_pipe(pipe) 2110 2111 # Test for the presence of data, and end the execution of this function if there is none. 2112 if not exists_mol_res_spin_data(pipe=pipe): 2113 return 2114 2115 # Parse the selection string. 2116 select_obj = Selection(selection) 2117 2118 # Loop over the molecules. 2119 for mol in dp.mol: 2120 # Skip the molecule if there is no match to the selection. 2121 if not select_obj.contains_mol(mol.name): 2122 continue 2123 2124 # Generate the spin id. 2125 if return_id: 2126 mol_id = generate_spin_id(pipe_cont=dp, mol_name=mol.name) 2127 2128 # Yield the molecule data container. 2129 if return_id: 2130 yield mol, mol_id 2131 else: 2132 yield mol
2133 2134
2135 -def name_molecule(mol_id, name=None, force=False):
2136 """Name the molecules. 2137 2138 @param mol_id: The molecule identification string. 2139 @type mol_id: str 2140 @param name: The new molecule name. 2141 @type name: str 2142 @keyword force: A flag which if True will cause the named molecule to be renamed. 2143 @type force: bool 2144 """ 2145 2146 # Acquire the spin lock (data modifying function), and make sure it is finally released. 2147 status.spin_lock.acquire(sys._getframe().f_code.co_name) 2148 try: 2149 2150 # Get the single molecule data container. 2151 mol = return_molecule(mol_id) 2152 2153 # Disallow residue and spin selections. 2154 select_obj = Selection(mol_id) 2155 if select_obj.has_residues(): 2156 raise RelaxResSelectDisallowError 2157 if select_obj.has_spins(): 2158 raise RelaxSpinSelectDisallowError 2159 2160 # Name the molecule is there is a single match. 2161 if mol: 2162 if mol.name and not force: 2163 warn(RelaxWarning("The molecule '%s' is already named. Set the force flag to rename." % mol_id)) 2164 else: 2165 mol.name = name 2166 2167 # Update the private metadata. 2168 metadata_cleanup(mol_index=mol._mol_index) 2169 metadata_update(mol_index=mol._mol_index) 2170 2171 # Release the lock. 2172 finally: 2173 status.spin_lock.release(sys._getframe().f_code.co_name)
2174 2175
2176 -def name_residue(res_id, name=None, force=False):
2177 """Name the residues. 2178 2179 @param res_id: The residue identification string. 2180 @type res_id: str 2181 @param name: The new residue name. 2182 @type name: str 2183 @keyword force: A flag which if True will cause the named residue to be renamed. 2184 @type force: bool 2185 """ 2186 2187 # Acquire the spin lock (data modifying function), and make sure it is finally released. 2188 status.spin_lock.acquire(sys._getframe().f_code.co_name) 2189 try: 2190 # Disallow spin selections. 2191 select_obj = Selection(res_id) 2192 if select_obj.has_spins(): 2193 raise RelaxSpinSelectDisallowError 2194 2195 # Rename the matching residues. 2196 for res, mol_name in residue_loop(res_id, full_info=True): 2197 if res.name and not force: 2198 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))) 2199 else: 2200 res.name = name 2201 2202 # Update the private metadata. 2203 metadata_cleanup(mol_index=res._mol_index, res_index=res._res_index) 2204 metadata_update(mol_index=res._mol_index, res_index=res._res_index) 2205 2206 # Release the lock. 2207 finally: 2208 status.spin_lock.release(sys._getframe().f_code.co_name)
2209 2210
2211 -def name_spin(spin_id=None, name=None, pipe=None, force=False):
2212 """Name the spins. 2213 2214 @keyword spin_id: The spin identification string. 2215 @type spin_id: str 2216 @keyword name: The new spin name. 2217 @type name: str 2218 @param pipe: The data pipe to operate on. Defaults to the current data pipe. 2219 @type pipe: str 2220 @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. 2221 @type force: bool or None 2222 """ 2223 2224 # The data pipe. 2225 if pipe == None: 2226 pipe = pipes.cdp_name() 2227 2228 # Test the data pipe. 2229 pipes.test(pipe) 2230 2231 # Acquire the spin lock (data modifying function), and make sure it is finally released. 2232 status.spin_lock.acquire(sys._getframe().f_code.co_name) 2233 try: 2234 # Rename the matching spins. 2235 for spin, id in spin_loop(spin_id, pipe=pipe, return_id=True): 2236 if spin.name and force != True: 2237 if force == False: 2238 warn(RelaxWarning("The spin '%s' is already named. Set the force flag to rename." % id)) 2239 else: 2240 warn(RelaxWarning("The spin '%s' is already named." % id)) 2241 else: 2242 spin.name = name 2243 2244 # Update the private metadata. 2245 metadata_cleanup(mol_index=spin._mol_index, res_index=spin._res_index, spin_index=spin._spin_index) 2246 metadata_update(mol_index=spin._mol_index, res_index=spin._res_index, spin_index=spin._spin_index) 2247 2248 # Release the lock. 2249 finally: 2250 status.spin_lock.release(sys._getframe().f_code.co_name)
2251 2252
2253 -def number_residue(res_id, number=None, force=False):
2254 """Number the residues. 2255 2256 @param res_id: The residue identification string. 2257 @type res_id: str 2258 @param number: The new residue number. 2259 @type number: int 2260 @keyword force: A flag which if True will cause the numbered residue to be renumbered. 2261 @type force: bool 2262 """ 2263 2264 # Acquire the spin lock (data modifying function), and make sure it is finally released. 2265 status.spin_lock.acquire(sys._getframe().f_code.co_name) 2266 try: 2267 # Catch multiple numberings! 2268 i = 0 2269 for res in residue_loop(res_id): 2270 i = i + 1 2271 2272 # Fail if multiple residues are numbered. 2273 if i > 1: 2274 raise RelaxError("The numbering of multiple residues is disallowed, each residue requires a unique number.") 2275 2276 # Disallow spin selections. 2277 select_obj = Selection(res_id) 2278 if select_obj.has_spins(): 2279 raise RelaxSpinSelectDisallowError 2280 2281 # Rename the residue. 2282 for res, mol_name in residue_loop(res_id, full_info=True): 2283 if res.num and not force: 2284 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))) 2285 else: 2286 res.num = number 2287 2288 # Update the private metadata. 2289 metadata_cleanup(mol_index=res._mol_index, res_index=res._res_index) 2290 metadata_update(mol_index=res._mol_index, res_index=res._res_index) 2291 2292 # Release the lock. 2293 finally: 2294 status.spin_lock.release(sys._getframe().f_code.co_name)
2295 2296
2297 -def number_spin(spin_id=None, number=None, force=False):
2298 """Number the spins. 2299 2300 @param spin_id: The spin identification string. 2301 @type spin_id: str 2302 @param number: The new spin number. 2303 @type number: int 2304 @keyword force: A flag which if True will cause the numbered spin to be renumbered. 2305 @type force: bool 2306 """ 2307 2308 # Acquire the spin lock (data modifying function), and make sure it is finally released. 2309 status.spin_lock.acquire(sys._getframe().f_code.co_name) 2310 try: 2311 # Catch multiple renumberings! 2312 i = 0 2313 for spin in spin_loop(spin_id): 2314 i = i + 1 2315 2316 # Fail if multiple spins are numbered. 2317 if number != None and i > 1: 2318 raise RelaxError("The numbering of multiple spins is disallowed, as each spin requires a unique number.") 2319 2320 # Rename the spin. 2321 for spin, id in spin_loop(spin_id, return_id=True): 2322 if spin.num and not force: 2323 warn(RelaxWarning("The spin '%s' is already numbered. Set the force flag to renumber." % id)) 2324 else: 2325 spin.num = number 2326 2327 # Update the private metadata. 2328 metadata_cleanup(mol_index=spin._mol_index, res_index=spin._res_index, spin_index=spin._spin_index) 2329 metadata_update(mol_index=spin._mol_index, res_index=spin._res_index, spin_index=spin._spin_index) 2330 2331 # Release the lock. 2332 finally: 2333 status.spin_lock.release(sys._getframe().f_code.co_name)
2334 2335
2336 -def one_letter_code(res_names):
2337 """Convert the list of residue names into a string of one letter residue codes. 2338 2339 Standard amino acids are converted to the one letter code. Unknown residues are labelled as 'X'. 2340 2341 2342 @param res_names: A list of residue names. 2343 @type res_names: list or str 2344 @return: The one letter codes for the residues. 2345 @rtype: str 2346 """ 2347 2348 # The amino acid translation table. 2349 aa_table = [ 2350 ['Alanine', 'ALA', 'A'], 2351 ['Arginine', 'ARG', 'R'], 2352 ['Asparagine', 'ASN', 'N'], 2353 ['Aspartic acid', 'ASP', 'D'], 2354 ['Cysteine', 'CYS', 'C'], 2355 ['Glutamic acid', 'GLU', 'E'], 2356 ['Glutamine', 'GLN', 'Q'], 2357 ['Glycine', 'GLY', 'G'], 2358 ['Histidine', 'HIS', 'H'], 2359 ['Isoleucine', 'ILE', 'I'], 2360 ['Leucine', 'LEU', 'L'], 2361 ['Lysine', 'LYS', 'K'], 2362 ['Methionine', 'MET', 'M'], 2363 ['Phenylalanine', 'PHE', 'F'], 2364 ['Proline', 'PRO', 'P'], 2365 ['Serine', 'SER', 'S'], 2366 ['Threonine', 'THR', 'T'], 2367 ['Tryptophan', 'TRP', 'W'], 2368 ['Tyrosine', 'TYR', 'Y'], 2369 ['Valine', 'VAL', 'V'] 2370 ] 2371 2372 # Translate. 2373 seq = '' 2374 for res in res_names: 2375 # Aa match. 2376 match = False 2377 for i in range(len(aa_table)): 2378 if res.upper() == aa_table[i][1]: 2379 seq = seq + aa_table[i][2] 2380 match = True 2381 break 2382 2383 # No match. 2384 if not match: 2385 seq = seq + 'X' 2386 2387 # Return the sequence. 2388 return seq
2389 2390
2391 -def pseudoatom_loop(spin=None, return_id=False):
2392 """Loop over the atoms of the given pseudo-atom spin container. 2393 2394 @keyword spin: The pseudo-atom spin container. 2395 @type spin: SpinContainer instance 2396 @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. 2397 @type return_id: bool 2398 @return: The spins of the pseudo-atom. 2399 @rtype: SpinContainer instance 2400 """ 2401 2402 # Check for the 'members' data structure. 2403 if not hasattr(spin, 'members'): 2404 return 2405 2406 # Loop over the members. 2407 for spin_id in spin.members: 2408 # Get the spin container. 2409 spin = return_spin(spin_id=spin_id) 2410 2411 # Yield the data. 2412 if return_id: 2413 yield spin, spin_id 2414 else: 2415 yield spin
2416 2417
2418 -def residue_loop(selection=None, pipe=None, full_info=False, return_id=False):
2419 """Generator function for looping over all the residues of the given selection. 2420 2421 @param selection: The residue selection identifier. 2422 @type selection: str 2423 @param pipe: The data pipe containing the residue. Defaults to the current data pipe. 2424 @type pipe: str 2425 @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. 2426 @type full_info: boolean 2427 @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. 2428 @type return_id: bool 2429 @return: The residue specific data container and, if full_info=True, the molecule name. 2430 @rtype: instance of the ResidueContainer class. If full_info=True, the type is the tuple (ResidueContainer, str). 2431 """ 2432 2433 # The data pipe. 2434 if pipe == None: 2435 pipe = pipes.cdp_name() 2436 2437 # Test the data pipe. 2438 pipes.test(pipe) 2439 2440 # Get the data pipe. 2441 dp = pipes.get_pipe(pipe) 2442 2443 # Test for the presence of data, and end the execution of this function if there is none. 2444 if not exists_mol_res_spin_data(pipe=pipe): 2445 return 2446 2447 # Parse the selection string. 2448 select_obj = Selection(selection) 2449 2450 # Loop over the molecules. 2451 for mol in dp.mol: 2452 # Loop over the residues. 2453 for res in mol.res: 2454 # Skip the residue if there is no match to the selection. 2455 if not select_obj.contains_res(res_num=res.num, res_name=res.name, mol=mol.name): 2456 continue 2457 2458 # Generate the spin id. 2459 if return_id: 2460 res_id = generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_num=res.num, res_name=res.name) 2461 2462 # Yield the residue data container. 2463 if full_info and return_id: 2464 yield res, mol.name, res_id 2465 elif full_info: 2466 yield res, mol.name 2467 elif return_id: 2468 yield res, res_id 2469 else: 2470 yield res
2471 2472
2473 -def return_molecule(selection=None, pipe=None):
2474 """Function for returning the molecule data container of the given selection. 2475 2476 @param selection: The molecule selection identifier. 2477 @type selection: str 2478 @param pipe: The data pipe containing the molecule. Defaults to the current data pipe. 2479 @type pipe: str 2480 @return: The molecule specific data container. 2481 @rtype: instance of the MoleculeContainer class. 2482 """ 2483 2484 # The data pipe. 2485 if pipe == None: 2486 pipe = pipes.cdp_name() 2487 2488 # Test the data pipe. 2489 pipes.test(pipe) 2490 2491 # Get the data pipe. 2492 dp = pipes.get_pipe(pipe) 2493 2494 # Parse the selection string. 2495 select_obj = Selection(selection) 2496 2497 # Loop over the molecules. 2498 mol_num = 0 2499 mol_container = None 2500 for mol in dp.mol: 2501 # Skip the molecule if there is no match to the selection. 2502 if not select_obj.contains_mol(mol=mol.name): 2503 continue 2504 2505 # Skip named molecules if the selection is None. 2506 if selection == None and mol.name != None: 2507 continue 2508 2509 # Store the molecule container. 2510 mol_container = mol 2511 2512 # Increment the molecule number counter. 2513 mol_num = mol_num + 1 2514 2515 # No unique identifier. 2516 if mol_num > 1: 2517 raise RelaxMultiMolIDError(selection) 2518 2519 # Return the molecule container. 2520 return mol_container
2521 2522
2523 -def return_molecule_by_name(pipe_cont=None, pipe_name=None, mol_name=None):
2524 """Return the molecule container matching the given name. 2525 2526 @keyword pipe_cont: The data pipe object. 2527 @type pipe_cont: PipeContainer instance 2528 @keyword pipe_name: The data pipe name. 2529 @type pipe_name: str 2530 @keyword mol_name: The molecule name. If not supplied and only a single molecule container exists, then that container will be returned. 2531 @type mol_name: str 2532 @return: The molecule container object. 2533 @rtype: MoleculeContainer instance 2534 """ 2535 2536 # The data pipe. 2537 if pipe_cont == None: 2538 pipe_cont = pipes.get_pipe(pipe) 2539 2540 # No molecule name specified, so assume a single molecule. 2541 if mol_name == None: 2542 # More than one molecule. 2543 if len(pipe_cont.mol) > 1: 2544 raise RelaxError("Cannot return the molecule with no name as more than one molecule exists.") 2545 2546 # Return the molecule. 2547 return pipe_cont.mol[0] 2548 2549 # Loop over the molecules. 2550 for mol in pipe_cont.mol: 2551 # Return the matching molecule. 2552 if mol.name == mol_name: 2553 return mol
2554 2555
2556 -def return_residue(selection=None, pipe=None, indices=False):
2557 """Function for returning the residue data container of the given selection. 2558 2559 @param selection: The residue selection identifier. 2560 @type selection: str 2561 @param pipe: The data pipe containing the residue. Defaults to the current data pipe. 2562 @type pipe: str 2563 @return: The residue specific data container, and the molecule and residue indices if asked. 2564 @rtype: instance of the ResidueContainer class. 2565 """ 2566 2567 # The data pipe. 2568 if pipe == None: 2569 pipe = pipes.cdp_name() 2570 2571 # Test the data pipe. 2572 pipes.test(pipe) 2573 2574 # Get the data pipe. 2575 dp = pipes.get_pipe(pipe) 2576 2577 # Parse the selection string. 2578 select_obj = Selection(selection) 2579 2580 # Loop over the molecules. 2581 res = None 2582 res_num = 0 2583 res_container = None 2584 for i in range(len(dp.mol)): 2585 # Skip the molecule if there is no match to the selection. 2586 if not select_obj.contains_mol(mol=dp.mol[i].name): 2587 continue 2588 2589 # Store the molecule index. 2590 mol_index = i 2591 2592 # Loop over the residues. 2593 for j in range(len(dp.mol[i].res)): 2594 # Skip the residue if there is no match to the selection. 2595 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): 2596 continue 2597 2598 # Store the residue container and index. 2599 res_container = dp.mol[i].res[j] 2600 res_index = j 2601 2602 # Increment the residue number counter. 2603 res_num = res_num + 1 2604 2605 # No unique identifier. 2606 if res_num > 1: 2607 raise RelaxMultiResIDError(selection) 2608 2609 # Return the residue container. 2610 if indices: 2611 return res_container, mol_index, res_index 2612 else: 2613 return res_container
2614 2615
2616 -def return_residue_by_info(mol=None, res_name=None, res_num=None):
2617 """Return the residue container matching the given name. 2618 2619 @keyword mol: The molecule container. 2620 @type mol: MoleculeContainer instance 2621 @keyword res_name: The residue name. If not supplied and only a single residue container exists, then that container will be returned. 2622 @type res_name: str 2623 @keyword res_num: The residue number. If not supplied and only a single residue container exists, then that container will be returned. 2624 @type res_num: str 2625 @return: The residue container object. 2626 @rtype: ResidueContainer instance 2627 """ 2628 2629 # No residue name or number specified, so assume a single residue. 2630 if res_name == None and res_num == None: 2631 # More than one residue. 2632 if len(mol.res) > 1: 2633 raise RelaxError("Cannot return the residue with no name or number as more than one residue exists.") 2634 2635 # Return the residue. 2636 return mol.res[0] 2637 2638 # Loop over the residues. 2639 for res in mol.res: 2640 # Return the matching residue. 2641 if res_name != None and res_num != None: 2642 if res.name == res_name and res.num == res_num: 2643 return res 2644 elif res_name != None: 2645 if res.name == res_name: 2646 return res 2647 elif res_num != None: 2648 if res.num == res_num: 2649 return res
2650 2651
2652 -def return_spin(spin_id=None, pipe=None, full_info=False, multi=False):
2653 """Return the spin data container corresponding to the given spin ID string. 2654 2655 @keyword spin_id: The unique spin ID string. 2656 @type spin_id: str 2657 @keyword pipe: The data pipe containing the spin. Defaults to the current data pipe. 2658 @type pipe: str 2659 @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. 2660 @type full_info: bool 2661 @keyword multi: A flag which if True will allow multiple spins to be returned. 2662 @type multi: bool 2663 @return: The spin system specific data container and, if full_info=True, the molecule name, residue number, and residue name. 2664 @rtype: SpinContainer instance of list of instances or tuple of (str, int, str, SpinContainer instance or list of instances) 2665 """ 2666 2667 # The data pipe. 2668 if pipe == None: 2669 pipe = pipes.cdp_name() 2670 2671 # Get the data pipe. 2672 dp = pipes.get_pipe(pipe) 2673 2674 # No spin ID, so assume there is no spin. 2675 if spin_id not in dp.mol._spin_id_lookup: 2676 return None 2677 2678 # The indices from the look up table. 2679 else: 2680 mol_index, res_index, spin_index = dp.mol._spin_id_lookup[spin_id] 2681 2682 # Return the data. 2683 if full_info and multi: 2684 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]] 2685 elif full_info: 2686 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] 2687 elif multi: 2688 return [dp.mol[mol_index].res[res_index].spin[spin_index]] 2689 else: 2690 return dp.mol[mol_index].res[res_index].spin[spin_index]
2691 2692
2693 -def return_spin_by_info(res=None, spin_name=None, spin_num=None):
2694 """Return the spin container matching the given name. 2695 2696 @keyword res: The residue container. 2697 @type res: ResidueContainer instance 2698 @keyword spin_name: The spin name. If not supplied and only a single spin container exists, then that container will be returned. 2699 @type spin_name: str 2700 @keyword spin_num: The spin number. If not supplied and only a single spin container exists, then that container will be returned. 2701 @type spin_num: str 2702 @return: The spin container object. 2703 @rtype: SpinContainer instance 2704 """ 2705 2706 # No spin name or number specified, so assume a single spin. 2707 if spin_name == None and spin_num == None: 2708 # More than one spin. 2709 if len(res.spin) > 1: 2710 raise RelaxError("Cannot return the spin with no name or number as more than one spin exists.") 2711 2712 # Return the spin. 2713 return res.spin[0] 2714 2715 # Loop over the spins. 2716 for spin in res.spin: 2717 # Return the matching spin. 2718 if spin_name != None and spin_num != None: 2719 if spin.name == spin_name and spin.num == spin_num: 2720 return spin 2721 elif spin_name != None: 2722 if spin.name == spin_name: 2723 return spin 2724 elif spin_num != None: 2725 if spin.num == spin_num: 2726 return spin
2727 2728
2729 -def return_spin_from_selection(selection=None, pipe=None, full_info=False, multi=False):
2730 """Function for returning the spin data container of the given selection. 2731 2732 If more than one selection is given, then the boolean AND operation will be used to pull out the spin. 2733 2734 2735 @keyword selection: The spin selection identifier. 2736 @type selection: str 2737 @keyword pipe: The data pipe containing the spin. Defaults to the current data pipe. 2738 @type pipe: str 2739 @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. 2740 @type full_info: bool 2741 @keyword multi: A flag which if True will allow multiple spins to be returned. 2742 @type multi: bool 2743 @return: The spin system specific data container and, if full_info=True, the molecule name, residue number, and residue name. 2744 @rtype: SpinContainer instance of list of instances or tuple of (str, int, str, SpinContainer instance or list of instances) 2745 """ 2746 2747 # Handle Unicode. 2748 if is_unicode(selection): 2749 selection = str(selection) 2750 2751 # The data pipe. 2752 if pipe == None: 2753 pipe = pipes.cdp_name() 2754 2755 # Get the data pipe. 2756 dp = pipes.get_pipe(pipe) 2757 2758 # Parse the selection string. 2759 select_obj = Selection(selection) 2760 2761 # Loop over the molecules. 2762 spin_num = 0 2763 spins = [] 2764 mol_names = [] 2765 res_nums = [] 2766 res_names = [] 2767 spin_ids = [] 2768 for mol in dp.mol: 2769 # Skip the molecule if there is no match to the selection. 2770 if not select_obj.contains_mol(mol=mol.name): 2771 continue 2772 2773 # Loop over the residues. 2774 for res in mol.res: 2775 # Skip the residue if there is no match to the selection. 2776 if not select_obj.contains_res(res_num=res.num, res_name=res.name, mol=mol.name): 2777 continue 2778 2779 # Loop over the spins. 2780 for spin in res.spin: 2781 # Skip the spin if there is no match to the selection. 2782 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): 2783 continue 2784 2785 # Store all data. 2786 mol_names.append(mol.name) 2787 res_nums.append(res.num) 2788 res_names.append(res.name) 2789 spins.append(spin) 2790 2791 # Increment the spin number counter. 2792 spin_num = spin_num + 1 2793 2794 # Generate as store the spin ID. 2795 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)) 2796 2797 # No unique identifier. 2798 if not multi and spin_num > 1: 2799 raise RelaxMultiSpinIDError(selection, spin_ids) 2800 2801 # Return the spin container. 2802 if full_info and multi: 2803 return mol_names, res_nums, res_names, spins 2804 elif full_info: 2805 return mol_names[0], res_nums[0], res_names[0], spins[0] 2806 elif multi: 2807 return spins 2808 elif len(spins): 2809 return spins[0] 2810 else: 2811 return None
2812 2813
2814 -def return_spin_from_index(global_index=None, pipe=None, return_spin_id=False):
2815 """Function for returning the spin data container corresponding to the global index. 2816 2817 @param global_index: The global spin index, spanning the molecule and residue containers. 2818 @type global_index: int 2819 @param pipe: The data pipe containing the spin. Defaults to the current data pipe. 2820 @type pipe: str 2821 @keyword return_spin_id: A flag which if True will cause both the spin container and spin identification string to be returned. 2822 @type return_spin_id: bool 2823 @return: The spin specific data container (additionally the spin identification string if return_spin_id is set). 2824 @rtype: instance of the SpinContainer class (or tuple of SpinContainer and str) 2825 """ 2826 2827 # The data pipe. 2828 if pipe == None: 2829 pipe = pipes.cdp_name() 2830 2831 # Test the data pipe. 2832 pipes.test(pipe) 2833 2834 # Loop over the spins. 2835 spin_num = 0 2836 for spin, mol_name, res_num, res_name in spin_loop(full_info=True, pipe=pipe): 2837 # Match to the global index. 2838 if spin_num == global_index: 2839 # Return the spin and the spin_id string. 2840 if return_spin_id: 2841 # The spin identification string. 2842 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) 2843 2844 # Return both objects. 2845 return spin, spin_id 2846 2847 # Return the spin by itself. 2848 else: 2849 return spin 2850 2851 # Increment the spin number. 2852 spin_num = spin_num + 1
2853 2854
2855 -def return_spin_indices(spin_id=None, pipe=None):
2856 """Return the molecule, residue and spin indices corresponding to the given spin ID string. 2857 2858 @keyword spin_id: The unique spin ID string. 2859 @type spin_id: str 2860 @param pipe: The data pipe containing the spin. Defaults to the current data pipe. 2861 @type pipe: str 2862 @return: The molecule, residue and spin indices. 2863 @rtype: list of int 2864 """ 2865 2866 # The data pipe. 2867 if pipe == None: 2868 pipe = pipes.cdp_name() 2869 2870 # Get the data pipe. 2871 dp = pipes.get_pipe(pipe) 2872 2873 # No spin ID, so switch to selection matching. 2874 if spin_id not in dp.mol._spin_id_lookup: 2875 # Parse the selection string. 2876 select_obj = Selection(spin_id) 2877 2878 # Loop over the molecules. 2879 for i in range(len(dp.mol)): 2880 # Skip the molecule if there is no match to the selection. 2881 if not select_obj.contains_mol(mol=dp.mol[i].name): 2882 continue 2883 2884 # The molecule index. 2885 mol_index = i 2886 2887 # Loop over the residues. 2888 for j in range(len(dp.mol[i].res)): 2889 # Skip the residue if there is no match to the selection. 2890 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): 2891 continue 2892 2893 # The residue index. 2894 res_index = j 2895 2896 # Loop over the spins. 2897 for k in range(len(dp.mol[i].res[j].spin)): 2898 # Skip the spin if there is no match to the selection. 2899 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): 2900 continue 2901 2902 # The spin index. 2903 spin_index = k 2904 2905 # Found the spin, so terminate. 2906 break 2907 2908 # The indices from the look up table. 2909 else: 2910 mol_index, res_index, spin_index = dp.mol._spin_id_lookup[spin_id] 2911 2912 # Return the data. 2913 return mol_index, res_index, spin_index
2914 2915
2916 -def return_single_molecule_info(molecule_token):
2917 """Return the single molecule name corresponding to the molecule token. 2918 2919 @param molecule_token: The molecule identification string. 2920 @type molecule_token: str 2921 @return: The molecule name. 2922 @rtype: str 2923 """ 2924 2925 # Parse the molecule token for renaming and renumbering. 2926 molecule_info = parse_token(molecule_token) 2927 2928 # Determine the molecule name. 2929 mol_name = None 2930 for info in molecule_info: 2931 # A molecule name identifier. 2932 if mol_name == None: 2933 mol_name = info 2934 else: 2935 raise RelaxError("The molecule identifier " + repr(molecule_token) + " does not correspond to a single molecule.") 2936 2937 # Convert to a string if needed. 2938 if mol_name != None and not isinstance(mol_name, str): 2939 mol_name = str(mol_name) 2940 2941 # Return the molecule name. 2942 return mol_name
2943 2944
2945 -def return_single_residue_info(residue_token):
2946 """Return the single residue number and name corresponding to the residue token. 2947 2948 @param residue_token: The residue identification string. 2949 @type residue_token: str 2950 @return: A tuple containing the residue number and the residue name. 2951 @rtype: (int, str) 2952 """ 2953 2954 # Parse the residue token for renaming and renumbering. 2955 residue_info = parse_token(residue_token) 2956 2957 # Determine the residue number and name. 2958 res_num = None 2959 res_name = None 2960 for info in residue_info: 2961 # A residue name identifier. 2962 if isinstance(info, str): 2963 if res_name == None: 2964 res_name = info 2965 else: 2966 raise RelaxError("The residue identifier " + repr(residue_token) + " does not correspond to a single residue.") 2967 2968 # A residue number identifier. 2969 if isinstance(info, int): 2970 if res_num == None: 2971 res_num = info 2972 else: 2973 raise RelaxError("The residue identifier " + repr(residue_token) + " does not correspond to a single residue.") 2974 2975 # Return the residue number and name. 2976 return res_num, res_name
2977 2978
2979 -def return_single_spin_info(spin_token):
2980 """Return the single spin number and name corresponding to the spin token. 2981 2982 @param spin_token: The spin identification string. 2983 @type spin_token: str 2984 @return: A tuple containing the spin number and the spin name. 2985 @rtype: (int, str) 2986 """ 2987 2988 # Parse the spin token for renaming and renumbering. 2989 spin_info = parse_token(spin_token) 2990 2991 # Determine the spin number and name. 2992 spin_num = None 2993 spin_name = None 2994 for info in spin_info: 2995 # A spin name identifier. 2996 if isinstance(info, str): 2997 if spin_name == None: 2998 spin_name = info 2999 else: 3000 raise RelaxError("The spin identifier " + repr(spin_token) + " does not correspond to a single spin.") 3001 3002 # A spin number identifier. 3003 if isinstance(info, int): 3004 if spin_num == None: 3005 spin_num = info 3006 else: 3007 raise RelaxError("The spin identifier " + repr(spin_token) + " does not correspond to a single spin.") 3008 3009 # Return the spin number and name. 3010 return spin_num, spin_name
3011 3012
3013 -def same_sequence(pipe1, pipe2):
3014 """Test if the sequence data in both pipes are the same. 3015 3016 @param pipe1: The first data pipe. 3017 @type pipe1: str 3018 @param pipe2: The second data pipe. 3019 @type pipe2: str 3020 @return: True if the sequence data matches, False otherwise. 3021 @rtype: bool 3022 """ 3023 3024 # Test the data pipes. 3025 pipes.test(pipe1) 3026 pipes.test(pipe2) 3027 3028 # Get the data pipes. 3029 pipe1 = pipes.get_pipe(pipe1) 3030 pipe2 = pipes.get_pipe(pipe2) 3031 3032 # Different number of molecules. 3033 if len(pipe1.mol) != len(pipe2.mol): 3034 return False 3035 3036 # Loop over the molecules. 3037 for i in range(len(pipe1.mol)): 3038 # Different number of residues. 3039 if len(pipe1.mol[i].res) != len(pipe2.mol[i].res): 3040 return False 3041 3042 # Loop over the residues. 3043 for j in range(len(pipe1.mol[i].res)): 3044 # Different number of spins. 3045 if len(pipe1.mol[i].res[j].spin) != len(pipe2.mol[i].res[j].spin): 3046 return False 3047 3048 # Loop over the spins. 3049 for k in range(len(pipe1.mol[i].res[j].spin)): 3050 # Different spin numbers. 3051 if pipe1.mol[i].res[j].spin[k].num != pipe2.mol[i].res[j].spin[k].num: 3052 return False 3053 3054 # Different spin names. 3055 if pipe1.mol[i].res[j].spin[k].name != pipe2.mol[i].res[j].spin[k].name: 3056 return False 3057 3058 # The sequence is the same. 3059 return True
3060 3061
3062 -def set_spin_element(spin_id=None, element=None, pipe=None, force=False):
3063 """Set the element type of the spins. 3064 3065 @keyword spin_id: The spin identification string. 3066 @type spin_id: str 3067 @keyword element: The IUPAC element name. 3068 @type element: str 3069 @param pipe: The data pipe to operate on. Defaults to the current data pipe. 3070 @type pipe: str 3071 @keyword force: A flag which if True will cause the element to be changed. 3072 @type force: bool 3073 """ 3074 3075 # Valid names (for NMR active spins). 3076 valid_names = ['H', 3077 'C', 3078 'N', 3079 'O', 3080 'F', 3081 'Na', 3082 'P', 3083 'Cd' 3084 ] 3085 3086 # Check. 3087 if element not in valid_names: 3088 raise RelaxError("The element name '%s' is not valid and should be one of the IUPAC names %s." % (element, valid_names)) 3089 3090 # The data pipe. 3091 if pipe == None: 3092 pipe = pipes.cdp_name() 3093 3094 # Test the data pipe. 3095 pipes.test(pipe) 3096 3097 # Set the element name for the matching spins. 3098 for spin, id in spin_loop(spin_id, pipe=pipe, return_id=True): 3099 if hasattr(spin, 'element') and spin.element and not force: 3100 warn(RelaxWarning("The element type of the spin '%s' is already set. Set the force flag to True to rename." % id)) 3101 else: 3102 spin.element = element
3103 3104
3105 -def set_spin_isotope(spin_id=None, isotope=None, pipe=None, force=False):
3106 """Set the nuclear isotope type of the spins. 3107 3108 @keyword spin_id: The spin identification string. 3109 @type spin_id: str 3110 @keyword isotope: The nuclear isotope type. 3111 @type isotope: str 3112 @param pipe: The data pipe to operate on. Defaults to the current data pipe. 3113 @type pipe: str 3114 @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. 3115 @type force: bool or None 3116 """ 3117 3118 # Types currently supported in relax. 3119 supported_types = [ 3120 '1H', 3121 '2H', 3122 '13C', 3123 '14N', 3124 '15N', 3125 '17O', 3126 '19F', 3127 '23Na', 3128 '31P', 3129 '113Cd' 3130 ] 3131 3132 # Check. 3133 if isotope not in supported_types: 3134 raise RelaxError("The nuclear isotope type '%s' is currently not supported." % isotope) 3135 3136 # The data pipe. 3137 if pipe == None: 3138 pipe = pipes.cdp_name() 3139 3140 # Test the data pipe. 3141 pipes.test(pipe) 3142 3143 # Set the isotope type for the matching spins. 3144 for spin, id in spin_loop(spin_id, pipe=pipe, return_id=True): 3145 if hasattr(spin, 'isotope') and spin.isotope and force != True: 3146 if force == False: 3147 warn(RelaxWarning("The nuclear isotope type of the spin '%s' is already set. Change the force flag to True to reset." % id)) 3148 else: 3149 warn(RelaxWarning("The nuclear isotope type of the spin '%s' is already set." % id)) 3150 else: 3151 spin.isotope = isotope
3152 3153
3154 -def spin_id_variants(dp=None, mol_index=None, res_index=None, spin_index=None):
3155 """Generate a list of spin ID variants for the given set of molecule, residue and spin indices. 3156 3157 @keyword dp: The data pipe to work on. 3158 @type dp: PipeContainer instance 3159 @keyword mol_index: The molecule index. 3160 @type mol_index: int 3161 @keyword res_index: The residue index. 3162 @type res_index: int 3163 @keyword spin_index: The spin index. 3164 @type spin_index: int 3165 @return: The list of all spin IDs matching the spin. 3166 @rtype: list of str 3167 """ 3168 3169 # Initialise. 3170 spin_ids = [] 3171 mol = dp.mol[mol_index] 3172 res = dp.mol[mol_index].res[res_index] 3173 spin = dp.mol[mol_index].res[res_index].spin[spin_index] 3174 mol_count = len(dp.mol) 3175 res_count = len(mol.res) 3176 spin_count = len(res.spin) 3177 3178 # Unique top level info. 3179 unique_top_level_res_name = True 3180 unique_top_level_res_num = True 3181 unique_top_level_spin_name = True 3182 unique_top_level_spin_num = True 3183 if res.name != None and dp.mol._res_name_count[res.name] > 1: 3184 unique_top_level_res_name = False 3185 if res.num != None and dp.mol._res_num_count[res.num] > 1: 3186 unique_top_level_res_num = False 3187 if spin.name != None and dp.mol._spin_name_count[spin.name] > 1: 3188 unique_top_level_spin_name = False 3189 if spin.num != None and dp.mol._spin_num_count[spin.num] > 1: 3190 unique_top_level_spin_num = False 3191 3192 # Unique molecule level info. 3193 unique_mol_level_res_name = True 3194 unique_mol_level_res_num = True 3195 unique_mol_level_spin_name = True 3196 unique_mol_level_spin_num = True 3197 if res.name != None and mol._res_name_count[res.name] > 1: 3198 unique_mol_level_res_name = False 3199 if res.num != None and mol._res_num_count[res.num] > 1: 3200 unique_mol_level_res_num = False 3201 if spin.name != None and mol._spin_name_count[spin.name] > 1: 3202 unique_mol_level_spin_name = False 3203 if spin.num != None and mol._spin_num_count[spin.num] > 1: 3204 unique_mol_level_spin_num = False 3205 3206 # Unique residue level info. 3207 unique_res_level_spin_name = True 3208 unique_res_level_spin_num = True 3209 if spin.name != None and res._spin_name_count[spin.name] > 1: 3210 unique_res_level_spin_name = False 3211 if spin.num != None and res._spin_num_count[spin.num] > 1: 3212 unique_res_level_spin_num = False 3213 3214 # IDs with the molecule name. 3215 if mol.name != None: 3216 # IDs with the residue name. 3217 if res.name != None: 3218 # The molecule name, residue name and spin name. 3219 if spin.name != None and unique_mol_level_res_name and unique_res_level_spin_name: 3220 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_name=res.name, spin_name=spin.name)) 3221 3222 # The molecule name, residue name and spin number. 3223 if spin.num != None and unique_mol_level_res_name and unique_res_level_spin_num: 3224 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_name=res.name, spin_num=spin.num)) 3225 3226 # The molecule name and residue name. 3227 if spin_count == 1 and unique_mol_level_res_name: 3228 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_name=res.name)) 3229 3230 # IDs with the residue number. 3231 if res.num != None: 3232 # The molecule name, residue number and spin name. 3233 if spin.name != None and unique_mol_level_res_num and unique_res_level_spin_name: 3234 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_num=res.num, spin_name=spin.name)) 3235 3236 # The molecule name, residue number and spin number. 3237 if spin.num != None and unique_mol_level_res_num and unique_res_level_spin_num: 3238 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_num=res.num, spin_num=spin.num)) 3239 3240 # The molecule name and residue number. 3241 if spin_count == 1 and unique_mol_level_res_num: 3242 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_num=res.num)) 3243 3244 # The molecule name and spin name. 3245 if spin.name != None and unique_mol_level_spin_name: 3246 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, spin_name=spin.name)) 3247 3248 # The molecule name and spin number. 3249 if spin.num != None and unique_mol_level_spin_num: 3250 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, spin_num=spin.num)) 3251 3252 # The molecule name. 3253 if spin_count == 1 and res_count == 1: 3254 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name)) 3255 3256 # IDs with the residue name. 3257 if res.name != None: 3258 # The residue name and spin name. 3259 if spin.name != None and unique_top_level_res_name and unique_res_level_spin_name: 3260 spin_ids.append(generate_spin_id(pipe_cont=dp, res_name=res.name, spin_name=spin.name)) 3261 3262 # The residue name and spin number. 3263 if spin.num != None and unique_top_level_res_name and unique_res_level_spin_num: 3264 spin_ids.append(generate_spin_id(pipe_cont=dp, res_name=res.name, spin_num=spin.num)) 3265 3266 # The residue name. 3267 if spin_count == 1 and unique_top_level_res_name: 3268 spin_ids.append(generate_spin_id(pipe_cont=dp, res_name=res.name)) 3269 3270 # IDs with the residue number. 3271 if res.num != None: 3272 # The residue number and spin name. 3273 if spin.name != None and unique_top_level_res_num and unique_res_level_spin_name: 3274 spin_ids.append(generate_spin_id(pipe_cont=dp, res_num=res.num, spin_name=spin.name)) 3275 3276 # The residue number and spin number. 3277 if spin.num != None and unique_top_level_res_num and unique_res_level_spin_num: 3278 spin_ids.append(generate_spin_id(pipe_cont=dp, res_num=res.num, spin_num=spin.num)) 3279 3280 # The residue number. 3281 if spin_count == 1 and unique_top_level_res_num: 3282 spin_ids.append(generate_spin_id(pipe_cont=dp, res_num=res.num)) 3283 3284 # The spin name. 3285 if spin.name != None and unique_top_level_spin_name: 3286 spin_ids.append(generate_spin_id(pipe_cont=dp, spin_name=spin.name)) 3287 3288 # The spin number. 3289 if spin.num != None and unique_top_level_spin_num: 3290 spin_ids.append(generate_spin_id(pipe_cont=dp, spin_num=spin.num)) 3291 3292 # Return the IDs. 3293 return spin_ids
3294 3295
3296 -def spin_id_variants_cleanup(dp=None, mol_index=None, res_index=None, spin_index=None):
3297 """Generate a list of spin ID variants to eliminate for the given set of molecule, residue and spin indices. 3298 3299 @keyword dp: The data pipe to work on. 3300 @type dp: PipeContainer instance 3301 @keyword mol_index: The molecule index. 3302 @type mol_index: int 3303 @keyword res_index: The residue index. 3304 @type res_index: int 3305 @keyword spin_index: The spin index. 3306 @type spin_index: int 3307 @return: The list of all spin IDs matching the spin. 3308 @rtype: list of str 3309 """ 3310 3311 # Initialise. 3312 spin_ids = [] 3313 mol = dp.mol[mol_index] 3314 res = dp.mol[mol_index].res[res_index] 3315 spin = dp.mol[mol_index].res[res_index].spin[spin_index] 3316 mol_count = len(dp.mol) 3317 res_count = len(mol.res) 3318 spin_count = len(res.spin) 3319 3320 # Unique top level info. 3321 unique_top_level_res_name = True 3322 unique_top_level_res_num = True 3323 unique_top_level_spin_name = True 3324 unique_top_level_spin_num = True 3325 if res.name != None and dp.mol._res_name_count[res.name] > 1: 3326 unique_top_level_res_name = False 3327 if res.num != None and dp.mol._res_num_count[res.num] > 1: 3328 unique_top_level_res_num = False 3329 if spin.name != None and dp.mol._spin_name_count[spin.name] > 1: 3330 unique_top_level_spin_name = False 3331 if spin.num != None and dp.mol._spin_num_count[spin.num] > 1: 3332 unique_top_level_spin_num = False 3333 3334 # Unique molecule level info. 3335 unique_mol_level_res_name = True 3336 unique_mol_level_res_num = True 3337 unique_mol_level_spin_name = True 3338 unique_mol_level_spin_num = True 3339 if res.name != None and mol._res_name_count[res.name] > 1: 3340 unique_mol_level_res_name = False 3341 if res.num != None and mol._res_num_count[res.num] > 1: 3342 unique_mol_level_res_num = False 3343 if spin.name != None and mol._spin_name_count[spin.name] > 1: 3344 unique_mol_level_spin_name = False 3345 if spin.num != None and mol._spin_num_count[spin.num] > 1: 3346 unique_mol_level_spin_num = False 3347 3348 # Unique residue level info. 3349 unique_res_level_spin_name = True 3350 unique_res_level_spin_num = True 3351 if spin.name != None and res._spin_name_count[spin.name] > 1: 3352 unique_res_level_spin_name = False 3353 if spin.num != None and res._spin_num_count[spin.num] > 1: 3354 unique_res_level_spin_num = False 3355 3356 # IDs with the molecule name. 3357 if mol.name != None: 3358 # IDs with the residue name. 3359 if res.name != None: 3360 # The molecule name, residue name and spin name. 3361 if spin.name != None and (not unique_mol_level_res_name or not unique_res_level_spin_name): 3362 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_name=res.name, spin_name=spin.name)) 3363 3364 # The molecule name, residue name and spin number. 3365 if spin.num != None and (not unique_mol_level_res_name or not unique_res_level_spin_num): 3366 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_name=res.name, spin_num=spin.num)) 3367 3368 # The molecule name and residue name. 3369 if not unique_mol_level_res_name or spin_count > 1: 3370 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_name=res.name)) 3371 3372 # IDs with the residue number. 3373 if res.num != None: 3374 # The molecule name, residue number and spin name. 3375 if spin.name != None and (not unique_mol_level_res_num or not unique_res_level_spin_name): 3376 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_num=res.num, spin_name=spin.name)) 3377 3378 # The molecule name, residue number and spin number. 3379 if spin.num != None and (not unique_mol_level_res_num or not unique_res_level_spin_num): 3380 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_num=res.num, spin_num=spin.num)) 3381 3382 # The molecule name and residue number. 3383 if not unique_mol_level_res_num or spin_count > 1: 3384 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_num=res.num)) 3385 3386 # The molecule name and spin name. 3387 if spin.name != None and not unique_mol_level_spin_name: 3388 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, spin_name=spin.name)) 3389 3390 # The molecule name and spin number. 3391 if spin.num != None and not unique_mol_level_spin_num: 3392 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, spin_num=spin.num)) 3393 3394 # The molecule name. 3395 if res_count > 1 or spin_count > 1: 3396 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name)) 3397 3398 # IDs with the residue name. 3399 if res.name != None: 3400 # The residue name and spin name. 3401 if spin.name != None and (not unique_top_level_res_name and not unique_top_level_spin_name): 3402 spin_ids.append(generate_spin_id(pipe_cont=dp, res_name=res.name, spin_name=spin.name)) 3403 3404 # The residue name and spin number. 3405 if spin.num != None and (not unique_top_level_res_name and not unique_top_level_spin_num): 3406 spin_ids.append(generate_spin_id(pipe_cont=dp, res_name=res.name, spin_num=spin.num)) 3407 3408 # The residue name. 3409 if not unique_top_level_res_name or spin_count > 1: 3410 spin_ids.append(generate_spin_id(pipe_cont=dp, res_name=res.name)) 3411 3412 # IDs with the residue number. 3413 if res.num != None: 3414 # The residue number and spin name. 3415 if spin.name != None and (not unique_top_level_res_num and not unique_top_level_spin_name): 3416 spin_ids.append(generate_spin_id(pipe_cont=dp, res_num=res.num, spin_name=spin.name)) 3417 3418 # The residue number and spin number. 3419 if spin.num != None and (not unique_top_level_res_num and not unique_top_level_spin_num): 3420 spin_ids.append(generate_spin_id(pipe_cont=dp, res_num=res.num, spin_num=spin.num)) 3421 3422 # The residue number. 3423 if not unique_top_level_res_num or spin_count > 1: 3424 spin_ids.append(generate_spin_id(pipe_cont=dp, res_num=res.num)) 3425 3426 # The spin name. 3427 if spin.name != None and not unique_top_level_spin_name: 3428 spin_ids.append(generate_spin_id(pipe_cont=dp, spin_name=spin.name)) 3429 3430 # The spin number. 3431 if spin.num != None and not unique_top_level_spin_num: 3432 spin_ids.append(generate_spin_id(pipe_cont=dp, spin_num=spin.num)) 3433 3434 # Return the IDs. 3435 return spin_ids
3436 3437
3438 -def spin_id_variants_prune(dp=None, mol_index=None, res_index=None, spin_index=None):
3439 """Generate a list of spin ID variants to eliminate for the given set of molecule, residue and spin indices. 3440 3441 @keyword dp: The data pipe to work on. 3442 @type dp: PipeContainer instance 3443 @keyword mol_index: The molecule index. 3444 @type mol_index: int 3445 @keyword res_index: The residue index. 3446 @type res_index: int 3447 @keyword spin_index: The spin index. 3448 @type spin_index: int 3449 @return: The list of all spin IDs matching the spin. 3450 @rtype: list of str 3451 """ 3452 3453 # Initialise. 3454 spin_ids = [] 3455 mol = dp.mol[mol_index] 3456 res = dp.mol[mol_index].res[res_index] 3457 spin = dp.mol[mol_index].res[res_index].spin[spin_index] 3458 mol_count = len(dp.mol) 3459 res_count = len(mol.res) 3460 spin_count = len(res.spin) 3461 3462 # IDs with the molecule name. 3463 if mol.name != None: 3464 # IDs with the residue name. 3465 if res.name != None: 3466 # The molecule name, residue name and spin name. 3467 if spin.name != None: 3468 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_name=res.name, spin_name=spin.name)) 3469 3470 # The molecule name, residue name and spin number. 3471 if spin.num != None: 3472 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_name=res.name, spin_num=spin.num)) 3473 3474 # The molecule name and residue name. 3475 if spin_count == 1: 3476 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_name=res.name)) 3477 3478 # IDs with the residue number. 3479 if res.num != None: 3480 # The molecule name, residue number and spin name. 3481 if spin.name != None: 3482 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_num=res.num, spin_name=spin.name)) 3483 3484 # The molecule name, residue number and spin number. 3485 if spin.num != None: 3486 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_num=res.num, spin_num=spin.num)) 3487 3488 # The molecule name and residue number. 3489 if spin_count == 1: 3490 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, res_num=res.num)) 3491 3492 # The molecule name and spin name. 3493 if spin.name != None and res_count == 1: 3494 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, spin_name=spin.name)) 3495 3496 # The molecule name and spin number. 3497 if spin.num != None and res_count == 1: 3498 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name, spin_num=spin.num)) 3499 3500 # The molecule name. 3501 if res_count == 1 and spin_count == 1: 3502 spin_ids.append(generate_spin_id(pipe_cont=dp, mol_name=mol.name)) 3503 3504 # IDs with the residue name. 3505 if res.name != None: 3506 # The residue name and spin name. 3507 if spin.name != None and mol_count == 1: 3508 spin_ids.append(generate_spin_id(pipe_cont=dp, res_name=res.name, spin_name=spin.name)) 3509 3510 # The residue name and spin number. 3511 if spin.num != None and mol_count == 1: 3512 spin_ids.append(generate_spin_id(pipe_cont=dp, res_name=res.name, spin_num=spin.num)) 3513 3514 # The residue name. 3515 if mol_count == 1 and spin_count == 1: 3516 spin_ids.append(generate_spin_id(pipe_cont=dp, res_name=res.name)) 3517 3518 # IDs with the residue number. 3519 if res.num != None: 3520 # The residue number and spin name. 3521 if spin.name != None and mol_count == 1: 3522 spin_ids.append(generate_spin_id(pipe_cont=dp, res_num=res.num, spin_name=spin.name)) 3523 3524 # The residue number and spin number. 3525 if spin.num != None and mol_count == 1: 3526 spin_ids.append(generate_spin_id(pipe_cont=dp, res_num=res.num, spin_num=spin.num)) 3527 3528 # The residue number. 3529 if mol_count == 1 and spin_count == 1: 3530 spin_ids.append(generate_spin_id(pipe_cont=dp, res_num=res.num)) 3531 3532 # The spin name. 3533 if spin.name != None and mol_count == 1 and res_count == 1: 3534 spin_ids.append(generate_spin_id(pipe_cont=dp, spin_name=spin.name)) 3535 3536 # The spin number. 3537 if spin.num != None and mol_count == 1 and res_count == 1: 3538 spin_ids.append(generate_spin_id(pipe_cont=dp, spin_num=spin.num)) 3539 3540 # Return the IDs. 3541 return spin_ids
3542 3543
3544 -def spin_index_loop(selection=None, pipe=None):
3545 """Generator function for looping over all selected spins, returning the mol-res-spin indices. 3546 3547 @param selection: The spin system selection identifier. 3548 @type selection: str 3549 @param pipe: The data pipe containing the spin. Defaults to the current data pipe. 3550 @type pipe: str 3551 @return: The molecule, residue, and spin index. 3552 @rtype: tuple of 3 int 3553 """ 3554 3555 # The data pipe. 3556 if pipe == None: 3557 pipe = pipes.cdp_name() 3558 3559 # Test the data pipe. 3560 pipes.test(pipe) 3561 3562 # Get the data pipe. 3563 dp = pipes.get_pipe(pipe) 3564 3565 # Test for the presence of data, and end the execution of this function if there is none. 3566 if not exists_mol_res_spin_data(pipe=pipe): 3567 return 3568 3569 # Parse the selection string. 3570 select_obj = Selection(selection) 3571 3572 # Loop over the molecules. 3573 for mol_index in range(len(dp.mol)): 3574 # Alias the molecule container. 3575 mol = dp.mol[mol_index] 3576 3577 # Loop over the residues. 3578 for res_index in range(len(dp.mol[mol_index].res)): 3579 # Alias the residue container. 3580 res = dp.mol[mol_index].res[res_index] 3581 3582 # Loop over the spins. 3583 for spin_index in range(len(dp.mol[mol_index].res[res_index].spin)): 3584 # Alias the spin container. 3585 spin = dp.mol[mol_index].res[res_index].spin[spin_index] 3586 3587 # Skip the spin if there is no match to the selection. 3588 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): 3589 continue 3590 3591 # Yield the spin system specific indices. 3592 yield mol_index, res_index, spin_index
3593 3594
3595 -def spin_loop(selection=None, pipe=None, full_info=False, return_id=False, skip_desel=False):
3596 """Generator function for looping over all the spin systems of the given selection. 3597 3598 @keyword selection: The spin system selection identifier. 3599 @type selection: str 3600 @keyword pipe: The data pipe containing the spin. Defaults to the current data pipe. 3601 @type pipe: str 3602 @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. 3603 @type full_info: bool 3604 @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. 3605 @type return_id: bool 3606 @keyword skip_desel: A flag which if True will cause deselected spins to be skipped. 3607 @type skip_desel: bool 3608 @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. 3609 @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) 3610 """ 3611 3612 # The data pipe. 3613 if pipe == None: 3614 pipe = pipes.cdp_name() 3615 3616 # Test the data pipe. 3617 pipes.test(pipe) 3618 3619 # Get the data pipe. 3620 dp = pipes.get_pipe(pipe) 3621 3622 # Test for the presence of data, and end the execution of this function if there is none. 3623 if not exists_mol_res_spin_data(pipe=pipe): 3624 return 3625 3626 # Parse the selection string. 3627 select_obj = Selection(selection) 3628 3629 # Loop over the molecules. 3630 for mol in dp.mol: 3631 # Loop over the residues. 3632 for res in mol.res: 3633 # Loop over the spins. 3634 for spin in res.spin: 3635 # Skip the spin if there is no match to the selection. 3636 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): 3637 continue 3638 3639 # Skip deselected spins. 3640 if skip_desel and not spin.select: 3641 continue 3642 3643 # Generate the spin id. 3644 if return_id: 3645 spin_id = generate_spin_id_unique(pipe_cont=dp, mol=mol, res=res, spin=spin) 3646 3647 # Yield the data. 3648 if full_info and return_id: 3649 yield spin, mol.name, res.num, res.name, spin_id 3650 elif full_info: 3651 yield spin, mol.name, res.num, res.name 3652 elif return_id: 3653 yield spin, spin_id 3654 else: 3655 yield spin
3656 3657
3658 -def type_molecule(mol_id, type=None, force=False):
3659 """Set the molecule type. 3660 3661 @param mol_id: The molecule identification string. 3662 @type mol_id: str 3663 @param type: The molecule type. 3664 @type type: str 3665 @keyword force: A flag which if True will cause the molecule type to be overwritten. 3666 @type force: bool 3667 """ 3668 3669 # Check the type. 3670 if type not in ALLOWED_MOL_TYPES: 3671 raise RelaxError("The molecule type '%s' must be one of %s." % (type, ALLOWED_MOL_TYPES)) 3672 3673 # Disallow residue and spin selections. 3674 select_obj = Selection(mol_id) 3675 if select_obj.has_residues(): 3676 raise RelaxResSelectDisallowError 3677 if select_obj.has_spins(): 3678 raise RelaxSpinSelectDisallowError 3679 3680 # Change the molecule types. 3681 for mol in molecule_loop(mol_id): 3682 if hasattr(mol, 'type') and mol.type and not force: 3683 warn(RelaxWarning("The molecule '%s' already has its type set. Set the force flag to change." % mol_id)) 3684 else: 3685 mol.type = type
3686