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