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