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