Package generic_fns :: Module selection
[hide private]
[frames] | no frames]

Source Code for Module generic_fns.selection

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2003-2012 Edward d'Auvergne                                   # 
  4  #                                                                             # 
  5  # This file is part of the program relax (http://www.nmr-relax.com).          # 
  6  #                                                                             # 
  7  # This program is free software: you can redistribute it and/or modify        # 
  8  # it under the terms of the GNU General Public License as published by        # 
  9  # the Free Software Foundation, either version 3 of the License, or           # 
 10  # (at your option) any later version.                                         # 
 11  #                                                                             # 
 12  # This program is distributed in the hope that it will be useful,             # 
 13  # but WITHOUT ANY WARRANTY; without even the implied warranty of              # 
 14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               # 
 15  # GNU General Public License for more details.                                # 
 16  #                                                                             # 
 17  # You should have received a copy of the GNU General Public License           # 
 18  # along with this program.  If not, see <http://www.gnu.org/licenses/>.       # 
 19  #                                                                             # 
 20  ############################################################################### 
 21   
 22  # Module docstring. 
 23  """Module for selecting and deselecting spins.""" 
 24   
 25  # Python module imports 
 26  from warnings import warn 
 27   
 28  # relax module imports. 
 29  from generic_fns.interatomic import interatomic_loop 
 30  from generic_fns.mol_res_spin import exists_mol_res_spin_data, generate_spin_id, return_spin, spin_loop 
 31  from generic_fns import pipes 
 32  from relax_errors import RelaxError, RelaxNoSequenceError 
 33  from relax_io import read_spin_data 
 34  from relax_warnings import RelaxNoSpinWarning 
 35  from user_functions.data import Uf_tables; uf_tables = Uf_tables() 
 36  from user_functions.objects import Desc_container 
 37   
 38   
 39  boolean_doc = Desc_container("Boolean operators") 
 40  boolean_doc.add_paragraph("The boolean operator can be used to change how spin systems or interatomic data containers are selected.  The allowed values are: 'OR', 'NOR', 'AND', 'NAND', 'XOR', 'XNOR'.  The following table details how the selections will occur for the different boolean operators.") 
 41  table = uf_tables.add_table(label="table: bool operators", caption="Boolean operators and their effects on selections") 
 42  table.add_headings(["Spin system or interatomic data container", "1", "2", "3", "4", "5", "6", "7", "8", "9"]) 
 43  table.add_row(["Original selection", "0", "1", "1", "1", "1", "0", "1", "0", "1"]) 
 44  table.add_row(["New selection", "0", "1", "1", "1", "1", "1", "0", "0", "0"]) 
 45  table.add_row(["OR", "0", "1", "1", "1", "1", "1", "1", "0", "1"]) 
 46  table.add_row(["NOR", "1", "0", "0", "0", "0", "0", "0", "1", "0"]) 
 47  table.add_row(["AND", "0", "1", "1", "1", "1", "0", "0", "0", "0"]) 
 48  table.add_row(["NAND", "1", "0", "0", "0", "0", "1", "1", "1", "1"]) 
 49  table.add_row(["XOR", "0", "0", "0", "0", "0", "1", "1", "0", "1"]) 
 50  table.add_row(["XNOR", "1", "1", "1", "1", "1", "0", "0", "1", "0"]) 
 51  boolean_doc.add_table(table.label) 
 52   
 53   
54 -def desel_all():
55 """Deselect all spins. 56 57 @raises RelaxNoSequenceError: If no molecule/residue/spins sequence data exists. 58 """ 59 60 # Test if the current data pipe exists. 61 pipes.test() 62 63 # Test if sequence data is loaded. 64 if not exists_mol_res_spin_data(): 65 raise RelaxNoSequenceError 66 67 # Loop over the spins and deselect them. 68 for spin in spin_loop(): 69 spin.select = False
70 71
72 -def desel_interatom(spin_id1=None, spin_id2=None, boolean='AND', change_all=False):
73 """Deselect specific interatomic data containers. 74 75 @keyword spin_id1: The spin ID string of the first spin of the pair. 76 @type spin_id1: str or None 77 @keyword spin_id2: The spin ID string of the second spin of the pair. 78 @type spin_id2: str or None 79 @param boolean: The boolean operator used to deselect the spin systems with. It can be one of 'OR', 'NOR', 'AND', 'NAND', 'XOR', or 'XNOR'. This will be ignored if the change_all flag is set. 80 @type boolean: str 81 @keyword change_all: A flag which if True will cause all spins not specified in the file to be selected. Only the boolean operator 'AND' is compatible with this flag set to True (all others will be ignored). 82 @type change_all: bool 83 @raises RelaxNoSequenceError: If no molecule/residue/spins sequence data exists. 84 @raises RelaxError: If the boolean operator is unknown. 85 """ 86 87 # Test if the current data pipe exists. 88 pipes.test() 89 90 # Test if sequence data is loaded. 91 if not exists_mol_res_spin_data(): 92 raise RelaxNoSequenceError 93 94 # First select all interatom containers if the change_all flag is set. 95 if change_all: 96 # Interatomic data loop. 97 for interatom in interatomic_loop(selected=False): 98 interatom.select = True 99 100 # Interatomic data loop. 101 for interatom in interatomic_loop(selection1=spin_id1, selection2=spin_id2, selected=False): 102 # Deselect just the specified residues. 103 if change_all: 104 interatom.select = False 105 106 # Boolean selections. 107 else: 108 if boolean == 'OR': 109 interatom.select = interatom.select or False 110 elif boolean == 'NOR': 111 interatom.select = not (interatom.select or False) 112 elif boolean == 'AND': 113 interatom.select = interatom.select and False 114 elif boolean == 'NAND': 115 interatom.select = not (interatom.select and False) 116 elif boolean == 'XOR': 117 interatom.select = not (interatom.select and False) and (interatom.select or False) 118 elif boolean == 'XNOR': 119 interatom.select = (interatom.select and False) or not (interatom.select or False) 120 else: 121 raise RelaxError("Unknown boolean operator " + repr(boolean))
122 123
124 -def desel_read(file=None, dir=None, file_data=None, spin_id_col=None, mol_name_col=None, res_num_col=None, res_name_col=None, spin_num_col=None, spin_name_col=None, sep=None, spin_id=None, boolean='AND', change_all=False):
125 """Deselect the spins contained in the given file. 126 127 @keyword file: The name of the file to open. 128 @type file: str 129 @keyword dir: The directory containing the file (defaults to the current 130 directory if None). 131 @type dir: str or None 132 @keyword file_data: An alternative opening a file, if the data already exists in the 133 correct format. The format is a list of lists where the first 134 index corresponds to the row and the second the column. 135 @type file_data: list of lists 136 @keyword spin_id_col: The column containing the spin ID strings. If supplied, the 137 mol_name_col, res_name_col, res_num_col, spin_name_col, and 138 spin_num_col arguments must be none. 139 @type spin_id_col: int or None 140 @keyword mol_name_col: The column containing the molecule name information. If 141 supplied, spin_id_col must be None. 142 @type mol_name_col: int or None 143 @keyword res_name_col: The column containing the residue name information. If 144 supplied, spin_id_col must be None. 145 @type res_name_col: int or None 146 @keyword res_num_col: The column containing the residue number information. If 147 supplied, spin_id_col must be None. 148 @type res_num_col: int or None 149 @keyword spin_name_col: The column containing the spin name information. If supplied, 150 spin_id_col must be None. 151 @type spin_name_col: int or None 152 @keyword spin_num_col: The column containing the spin number information. If supplied, 153 spin_id_col must be None. 154 @type spin_num_col: int or None 155 @keyword sep: The column separator which, if None, defaults to whitespace. 156 @type sep: str or None 157 @keyword spin_id: The spin ID string used to restrict data loading to a subset of 158 all spins. 159 @type spin_id: None or str 160 @param boolean: The boolean operator used to deselect the spin systems with. It 161 can be one of 'OR', 'NOR', 'AND', 'NAND', 'XOR', or 'XNOR'. 162 This will be ignored if the change_all flag is set. 163 @type boolean: str 164 @keyword change_all: A flag which if True will cause all spins not specified in the 165 file to be selected. Only the boolean operator 'AND' is 166 compatible with this flag set to True (all others will be 167 ignored). 168 @type change_all: bool 169 @raises RelaxNoSequenceError: If no molecule/residue/spins sequence data exists. 170 @raises RelaxError: If the boolean operator is unknown. 171 """ 172 173 # Test if the current data pipe exists. 174 pipes.test() 175 176 # Test if sequence data is loaded. 177 if not exists_mol_res_spin_data(): 178 raise RelaxNoSequenceError 179 180 # First select all spins if the change_all flag is set. 181 if change_all: 182 for spin in spin_loop(): 183 spin.select = True 184 185 # Then deselect the spins in the file. 186 for mol_name, res_num, res_name, spin_num, spin_name in read_spin_data(file=file, dir=dir, file_data=file_data, spin_id_col=spin_id_col, mol_name_col=mol_name_col, res_num_col=res_num_col, res_name_col=res_name_col, spin_num_col=spin_num_col, spin_name_col=spin_name_col, sep=sep, spin_id=spin_id): 187 # Get the corresponding spin container. 188 id = generate_spin_id(mol_name=mol_name, res_num=res_num, res_name=res_name, spin_num=spin_num, spin_name=spin_name) 189 spin = return_spin(id) 190 191 # No spin. 192 if spin == None: 193 warn(RelaxNoSpinWarning(id)) 194 continue 195 196 # Deselect the spin. 197 if change_all: 198 spin.select = False 199 200 # Boolean selections. 201 else: 202 if boolean == 'OR': 203 spin.select = spin.select or False 204 elif boolean == 'NOR': 205 spin.select = not (spin.select or False) 206 elif boolean == 'AND': 207 spin.select = spin.select and False 208 elif boolean == 'NAND': 209 spin.select = not (spin.select and False) 210 elif boolean == 'XOR': 211 spin.select = not (spin.select and False) and (spin.select or False) 212 elif boolean == 'XNOR': 213 spin.select = (spin.select and False) or not (spin.select or False) 214 else: 215 raise RelaxError("Unknown boolean operator " + repr(boolean))
216 217
218 -def desel_spin(spin_id=None, boolean='AND', change_all=False):
219 """Deselect specific spins. 220 221 @keyword spin_id: The spin identification string. 222 @type spin_id: str or None 223 @param boolean: The boolean operator used to deselect the spin systems with. It 224 can be one of 'OR', 'NOR', 'AND', 'NAND', 'XOR', or 'XNOR'. 225 This will be ignored if the change_all flag is set. 226 @type boolean: str 227 @keyword change_all: A flag which if True will cause all spins not specified in the 228 file to be selected. Only the boolean operator 'AND' is 229 compatible with this flag set to True (all others will be 230 ignored). 231 @type change_all: bool 232 @raises RelaxNoSequenceError: If no molecule/residue/spins sequence data exists. 233 @raises RelaxError: If the boolean operator is unknown. 234 """ 235 236 # Test if the current data pipe exists. 237 pipes.test() 238 239 # Test if sequence data is loaded. 240 if not exists_mol_res_spin_data(): 241 raise RelaxNoSequenceError 242 243 # First select all spins if the change_all flag is set. 244 if change_all: 245 for spin in spin_loop(): 246 spin.select = True 247 248 # Loop over the specified spins. 249 for spin in spin_loop(spin_id): 250 # Deselect just the specified residues. 251 if change_all: 252 spin.select = False 253 254 # Boolean selections. 255 else: 256 if boolean == 'OR': 257 spin.select = spin.select or False 258 elif boolean == 'NOR': 259 spin.select = not (spin.select or False) 260 elif boolean == 'AND': 261 spin.select = spin.select and False 262 elif boolean == 'NAND': 263 spin.select = not (spin.select and False) 264 elif boolean == 'XOR': 265 spin.select = not (spin.select and False) and (spin.select or False) 266 elif boolean == 'XNOR': 267 spin.select = (spin.select and False) or not (spin.select or False) 268 else: 269 raise RelaxError("Unknown boolean operator " + repr(boolean))
270 271
272 -def is_mol_selected(selection=None):
273 """Query if the molecule is selected. 274 275 @keyword selection: The molecule ID string. 276 @type selection: str 277 """ 278 279 # Find if any spins are selected. 280 select = False 281 for spin in spin_loop(selection): 282 if spin.select: 283 select = True 284 break 285 286 # Return the state. 287 return select
288 289
290 -def is_res_selected(selection=None):
291 """Query if the residue is selected. 292 293 @keyword selection: The residue ID string. 294 @type selection: str 295 """ 296 297 # Find if any spins are selected. 298 select = False 299 for spin in spin_loop(selection): 300 if spin.select: 301 select = True 302 break 303 304 # Return the state. 305 return select
306 307
308 -def is_spin_selected(selection=None):
309 """Query if the spin is selected. 310 311 @keyword selection: The molecule ID string. 312 @type selection: str 313 """ 314 315 # Get the spin. 316 spin = return_spin(selection) 317 318 # Return the selected state. 319 return spin.select
320 321
322 -def reverse(spin_id=None):
323 """Reversal of spin selections. 324 325 @keyword spin_id: The spin identification string. 326 @type spin_id: str or None 327 @raises RelaxNoSequenceError: If no molecule/residue/spins sequence data exists. 328 """ 329 330 # Test if the current data pipe exists. 331 pipes.test() 332 333 # Test if sequence data is loaded. 334 if not exists_mol_res_spin_data(): 335 raise RelaxNoSequenceError 336 337 # Loop over the spin systems and reverse the selection flag. 338 for spin in spin_loop(spin_id): 339 # Reverse the selection. 340 if spin.select: 341 spin.select = False 342 else: 343 spin.select = True
344 345
346 -def sel_all():
347 """Select all residues. 348 349 @raises RelaxNoSequenceError: If no molecule/residue/spins sequence data exists. 350 """ 351 352 # Test if the current data pipe exists. 353 pipes.test() 354 355 # Test if sequence data is loaded. 356 if not exists_mol_res_spin_data(): 357 raise RelaxNoSequenceError 358 359 # Loop over the spins and select them. 360 for spin in spin_loop(): 361 spin.select = True
362 363
364 -def sel_interatom(spin_id1=None, spin_id2=None, boolean='OR', change_all=False):
365 """Select specific interatomic data containers. 366 367 @keyword spin_id1: The spin ID string of the first spin of the pair. 368 @type spin_id1: str or None 369 @keyword spin_id2: The spin ID string of the second spin of the pair. 370 @type spin_id2: str or None 371 @param boolean: The boolean operator used to select the spin systems with. It can be one of 'OR', 'NOR', 'AND', 'NAND', 'XOR', or 'XNOR'. This will be ignored if the change_all flag is set. 372 @type boolean: str 373 @keyword change_all: A flag which if True will cause all spins not specified in the file to be deselected. Only the boolean operator 'OR' is compatible with this flag set to True (all others will be ignored). 374 @type change_all: bool 375 @raises RelaxNoSequenceError: If no molecule/residue/spins sequence data exists. 376 @raises RelaxError: If the boolean operator is unknown. 377 """ 378 379 # Test if the current data pipe exists. 380 pipes.test() 381 382 # Test if sequence data is loaded. 383 if not exists_mol_res_spin_data(): 384 raise RelaxNoSequenceError 385 386 # First deselect all interatom containers if the change_all flag is set. 387 if change_all: 388 # Interatomic data loop. 389 for interatom in interatomic_loop(selected=False): 390 interatom.select = False 391 392 # Interatomic data loop. 393 for interatom in interatomic_loop(selection1=spin_id1, selection2=spin_id2, selected=False): 394 # Select just the specified containers. 395 if change_all: 396 interatom.select = True 397 398 # Boolean selections. 399 else: 400 if boolean == 'OR': 401 interatom.select = interatom.select or True 402 elif boolean == 'NOR': 403 interatom.select = not (interatom.select or True) 404 elif boolean == 'AND': 405 interatom.select = interatom.select and True 406 elif boolean == 'NAND': 407 interatom.select = not (interatom.select and True) 408 elif boolean == 'XOR': 409 interatom.select = not (interatom.select and True) and (interatom.select or True) 410 elif boolean == 'XNOR': 411 interatom.select = (interatom.select and True) or not (interatom.select or True) 412 else: 413 raise RelaxError("Unknown boolean operator " + repr(boolean))
414 415
416 -def sel_read(file=None, dir=None, file_data=None, spin_id_col=None, mol_name_col=None, res_num_col=None, res_name_col=None, spin_num_col=None, spin_name_col=None, sep=None, spin_id=None, boolean='OR', change_all=False):
417 """Select the spins contained in the given file. 418 419 @keyword file: The name of the file to open. 420 @type file: str 421 @keyword dir: The directory containing the file (defaults to the current 422 directory if None). 423 @type dir: str or None 424 @keyword file_data: An alternative opening a file, if the data already exists in the 425 correct format. The format is a list of lists where the first 426 index corresponds to the row and the second the column. 427 @type file_data: list of lists 428 @keyword spin_id_col: The column containing the spin ID strings. If supplied, the 429 mol_name_col, res_name_col, res_num_col, spin_name_col, and 430 spin_num_col arguments must be none. 431 @type spin_id_col: int or None 432 @keyword mol_name_col: The column containing the molecule name information. If 433 supplied, spin_id_col must be None. 434 @type mol_name_col: int or None 435 @keyword res_name_col: The column containing the residue name information. If 436 supplied, spin_id_col must be None. 437 @type res_name_col: int or None 438 @keyword res_num_col: The column containing the residue number information. If 439 supplied, spin_id_col must be None. 440 @type res_num_col: int or None 441 @keyword spin_name_col: The column containing the spin name information. If supplied, 442 spin_id_col must be None. 443 @type spin_name_col: int or None 444 @keyword spin_num_col: The column containing the spin number information. If supplied, 445 spin_id_col must be None. 446 @type spin_num_col: int or None 447 @keyword sep: The column separator which, if None, defaults to whitespace. 448 @type sep: str or None 449 @keyword spin_id: The spin ID string used to restrict data loading to a subset of 450 all spins. 451 @type spin_id: None or str 452 @param boolean: The boolean operator used to select the spin systems with. It 453 can be one of 'OR', 'NOR', 'AND', 'NAND', 'XOR', or 'XNOR'. 454 This will be ignored if the change_all flag is set. 455 @type boolean: str 456 @keyword change_all: A flag which if True will cause all spins not specified in the 457 file to be deselected. Only the boolean operator 'OR' is 458 compatible with this flag set to True (all others will be 459 ignored). 460 @type change_all: bool 461 @raises RelaxNoSequenceError: If no molecule/residue/spins sequence data exists. 462 @raises RelaxError: If the boolean operator is unknown. 463 """ 464 465 # Test if the current data pipe exists. 466 pipes.test() 467 468 # Test if sequence data is loaded. 469 if not exists_mol_res_spin_data(): 470 raise RelaxNoSequenceError 471 472 # First deselect all spins if the change_all flag is set. 473 if change_all: 474 # Loop over all spins. 475 for spin in spin_loop(): 476 spin.select = False 477 478 # Then deselect the spins in the file. 479 for id in read_spin_data(file=file, dir=dir, file_data=file_data, spin_id_col=spin_id_col, mol_name_col=mol_name_col, res_num_col=res_num_col, res_name_col=res_name_col, spin_num_col=spin_num_col, spin_name_col=spin_name_col, sep=sep, spin_id=spin_id): 480 # Get the corresponding spin container. 481 spin = return_spin(id) 482 483 # No spin. 484 if spin == None: 485 warn(RelaxNoSpinWarning(id)) 486 continue 487 488 # Select the spin. 489 if change_all: 490 spin.select = True 491 492 # Boolean selections. 493 else: 494 if boolean == 'OR': 495 spin.select = spin.select or True 496 elif boolean == 'NOR': 497 spin.select = not (spin.select or True) 498 elif boolean == 'AND': 499 spin.select = spin.select and True 500 elif boolean == 'NAND': 501 spin.select = not (spin.select and True) 502 elif boolean == 'XOR': 503 spin.select = not (spin.select and True) and (spin.select or True) 504 elif boolean == 'XNOR': 505 spin.select = (spin.select and True) or not (spin.select or True) 506 else: 507 raise RelaxError("Unknown boolean operator " + repr(boolean))
508 509
510 -def sel_spin(spin_id=None, boolean='OR', change_all=False):
511 """Select specific spins. 512 513 @keyword spin_id: The spin identification string. 514 @type spin_id: str or None 515 @param boolean: The boolean operator used to select the spin systems with. It 516 can be one of 'OR', 'NOR', 'AND', 'NAND', 'XOR', or 'XNOR'. 517 This will be ignored if the change_all flag is set. 518 @type boolean: str 519 @keyword change_all: A flag which if True will cause all spins not specified in the 520 file to be deselected. Only the boolean operator 'OR' is 521 compatible with this flag set to True (all others will be 522 ignored). 523 @type change_all: bool 524 @raises RelaxNoSequenceError: If no molecule/residue/spins sequence data exists. 525 @raises RelaxError: If the boolean operator is unknown. 526 """ 527 528 # Test if the current data pipe exists. 529 pipes.test() 530 531 # Test if sequence data is loaded. 532 if not exists_mol_res_spin_data(): 533 raise RelaxNoSequenceError 534 535 # First deselect all spins if the change_all flag is set. 536 if change_all: 537 # Loop over all spins. 538 for spin in spin_loop(): 539 spin.select = False 540 541 # Loop over the specified spins. 542 for spin in spin_loop(spin_id): 543 # Select just the specified residues. 544 if change_all: 545 spin.select = True 546 547 # Boolean selections. 548 else: 549 if boolean == 'OR': 550 spin.select = spin.select or True 551 elif boolean == 'NOR': 552 spin.select = not (spin.select or True) 553 elif boolean == 'AND': 554 spin.select = spin.select and True 555 elif boolean == 'NAND': 556 spin.select = not (spin.select and True) 557 elif boolean == 'XOR': 558 spin.select = not (spin.select and True) and (spin.select or True) 559 elif boolean == 'XNOR': 560 spin.select = (spin.select and True) or not (spin.select or True) 561 else: 562 raise RelaxError("Unknown boolean operator " + repr(boolean))
563