1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 """Module for selecting and deselecting spins."""
24
25
26 from warnings import warn
27
28
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
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
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
82 return state
83
84
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
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
113 return state
114
115
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
150 pipes.test()
151
152
153 if not exists_mol_res_spin_data():
154 raise RelaxNoSequenceError
155
156
157 if change_all:
158
159 for interatom in interatomic_loop(selected=False):
160 interatom.select = True
161
162
163 for interatom in interatomic_loop(selection1=spin_id1, selection2=spin_id2, selected=False):
164
165 if change_all:
166 interatom.select = False
167
168
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
223 pipes.test()
224
225
226 if not exists_mol_res_spin_data():
227 raise RelaxNoSequenceError
228
229
230 if change_all:
231 for spin in spin_loop():
232 spin.select = True
233
234
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
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
241 if spin == None:
242 warn(RelaxNoSpinWarning(id))
243 continue
244
245
246 if change_all:
247 spin.select = False
248
249
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
273 pipes.test()
274
275
276 if not exists_mol_res_spin_data():
277 raise RelaxNoSequenceError
278
279
280 if change_all:
281 for spin in spin_loop():
282 spin.select = True
283
284
285 for spin in spin_loop(spin_id):
286
287 if change_all:
288 spin.select = False
289
290
291 else:
292 spin.select = boolean_deselect(current=spin.select, boolean=boolean)
293
294
296 """Query if the molecule is selected.
297
298 @keyword selection: The molecule ID string.
299 @type selection: str
300 """
301
302
303 select = False
304 for spin in spin_loop(selection):
305 if spin.select:
306 select = True
307 break
308
309
310 return select
311
312
314 """Query if the residue is selected.
315
316 @keyword selection: The residue ID string.
317 @type selection: str
318 """
319
320
321 select = False
322 for spin in spin_loop(selection):
323 if spin.select:
324 select = True
325 break
326
327
328 return select
329
330
332 """Query if the spin is selected.
333
334 @keyword selection: The molecule ID string.
335 @type selection: str
336 """
337
338
339 spin = return_spin(selection)
340
341
342 return spin.select
343
344
367
368
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
403 pipes.test()
404
405
406 if not exists_mol_res_spin_data():
407 raise RelaxNoSequenceError
408
409
410 if change_all:
411
412 for interatom in interatomic_loop(selected=False):
413 interatom.select = False
414
415
416 for interatom in interatomic_loop(selection1=spin_id1, selection2=spin_id2, selected=False):
417
418 if change_all:
419 interatom.select = True
420
421
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
476 pipes.test()
477
478
479 if not exists_mol_res_spin_data():
480 raise RelaxNoSequenceError
481
482
483 if change_all:
484
485 for spin in spin_loop():
486 spin.select = False
487
488
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
491 spin = return_spin(id)
492
493
494 if spin == None:
495 warn(RelaxNoSpinWarning(id))
496 continue
497
498
499 if change_all:
500 spin.select = True
501
502
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
526 pipes.test()
527
528
529 if not exists_mol_res_spin_data():
530 raise RelaxNoSequenceError
531
532
533 if change_all:
534
535 for spin in spin_loop():
536 spin.select = False
537
538
539 for spin in spin_loop(spin_id):
540
541 if change_all:
542 spin.select = True
543
544
545 else:
546 spin.select = boolean_select(current=spin.select, boolean=boolean)
547