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

Source Code for Module generic_fns.selection

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