1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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
38 from numpy import array, float64
39 import sys
40 from warnings import warn
41
42
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
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
77 for spin in spin_loop(spin_id):
78
79 if spin.name != None:
80 return True
81
82
83 return False
84
85
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
94 for data in star.entity.loop():
95
96 mol_name = data['mol_name']
97 if mol_name:
98
99 mol_name = mol_name.replace('(', '')
100 mol_name = mol_name.replace(')', '')
101
102
103 mol_name = mol_name.replace('[', '')
104 mol_name = mol_name.replace(']', '')
105
106
107 mol_name = mol_name.replace(',', ' ')
108
109
110 mol_type = data['mol_type']
111 polymer_type = data['polymer_type']
112
113
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
127 create_molecule(mol_name=mol_name, mol_type=mol_type)
128
129
130 exp_info.thiol_state(data['thiol_state'])
131
132
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
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
147 for mol in molecule_loop():
148
149 if not mol.name:
150 raise RelaxError("All molecules must be named.")
151
152
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
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
161 res_names = get_residue_names("#" + mol.name)
162 res_nums = get_residue_nums("#" + mol.name)
163
164
165 polymer_seq_code = one_letter_code(res_names)
166
167
168 if mol.type in ['organic molecule', 'other']:
169 mol_type = 'non-polymer'
170 else:
171 mol_type = 'polymer'
172
173
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
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
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
216 status.spin_lock.acquire(sys._getframe().f_code.co_name)
217 try:
218
219 if pipe_from == None:
220 pipe_from = pipes.cdp_name()
221 if pipe_to == None:
222 pipe_to = pipes.cdp_name()
223
224
225 check_pipe(pipe_to)
226
227
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
232 if spin_from_token != None or spin_to_token != None:
233 raise RelaxSpinSelectDisallowError
234
235
236 if res_from_token != None or res_to_token != None:
237 raise RelaxResSelectDisallowError
238
239
240 mol_name_to = return_single_molecule_info(mol_to_token)
241
242
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
248 mol_from_cont = return_molecule(mol_from, pipe_from)
249
250
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
255 pipe = pipes.get_pipe(pipe_to)
256
257
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
264 if mol_name_to != None:
265 pipe.mol[-1].name = mol_name_to
266
267
268 metadata_update(pipe=pipe_to)
269
270
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
291 status.spin_lock.acquire(sys._getframe().f_code.co_name)
292 try:
293
294 if pipe_from == None:
295 pipe_from = pipes.cdp_name()
296 if pipe_to == None:
297 pipe_to = pipes.cdp_name()
298
299
300 check_pipe(pipe_to)
301
302
303 pipe = pipes.get_pipe(pipe_to)
304
305
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
310 if spin_from_token != None or spin_to_token != None:
311 raise RelaxSpinSelectDisallowError
312
313
314 res_num_to, res_name_to = return_single_residue_info(res_to_token)
315
316
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
322 res_from_cont = return_residue(res_from, pipe_from)
323
324
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
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
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
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
346 metadata_update(pipe=pipe_to)
347
348
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
370 status.spin_lock.acquire(sys._getframe().f_code.co_name)
371 try:
372
373 if pipe_from == None:
374 pipe_from = pipes.cdp_name()
375 if pipe_to == None:
376 pipe_to = pipes.cdp_name()
377
378
379 check_pipe(pipe_to)
380
381
382 pipe = pipes.get_pipe(pipe_to)
383
384
385 mol_to_token, res_to_token, spin_to_token = tokenise(spin_to)
386
387
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
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
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
403 res_to_cont = return_residue(spin_to, pipe_to)
404 if res_to_cont == None and spin_to:
405
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
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
417 spin_num_to, spin_name_to = return_single_spin_info(spin_to_token)
418
419
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
426 metadata_update(pipe=pipe_to)
427
428
429 finally:
430 status.spin_lock.release(sys._getframe().f_code.co_name)
431
432
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
447 if pipe == None:
448 pipe = pipes.cdp_name()
449
450
451 check_pipe(pipe)
452
453
454 if not exists_mol_res_spin_data(pipe=pipe):
455 return 0
456
457
458 max_num = 0
459
460
461 dp = pipes.get_pipe(pipe)
462
463
464 select_obj = Selection(spin_id)
465
466
467 for mol in dp.mol:
468
469 for res in mol.res:
470
471 spin_num = 0
472
473
474 for spin in res.spin:
475
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
480 if skip_desel and not spin.select:
481 continue
482
483
484 spin_num = spin_num + 1
485
486
487 max_num = max(max_num, spin_num)
488
489
490 return max_num
491
492
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
505 if pipe == None:
506 pipe = pipes.cdp_name()
507
508
509 check_pipe(pipe)
510
511
512 if not exists_mol_res_spin_data(pipe=pipe):
513 return 0
514
515
516 mol_num = 0
517
518
519 for mol in molecule_loop(selection, pipe=pipe):
520 mol_num = mol_num + 1
521
522
523 return mol_num
524
525
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
538 if pipe == None:
539 pipe = pipes.cdp_name()
540
541
542 check_pipe(pipe)
543
544
545 if not exists_mol_res_spin_data(pipe=pipe):
546 return 0
547
548
549 res_num = 0
550
551
552 for res in residue_loop(selection, pipe=pipe):
553 res_num = res_num + 1
554
555
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
573 if pipe == None:
574 pipe = pipes.cdp_name()
575
576
577 check_pipe(pipe)
578
579
580 if not exists_mol_res_spin_data(pipe=pipe):
581 return 0
582
583
584 spin_num = 0
585
586
587 for spin in spin_loop(selection, pipe=pipe):
588
589 if skip_desel and not spin.select:
590 continue
591
592 spin_num = spin_num + 1
593
594
595 return spin_num
596
597
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
612 if pipe == None:
613 pipe = pipes.cdp_name()
614
615
616 check_pipe(pipe)
617
618
619 dp = pipes.get_pipe(pipe)
620
621
622 status.spin_lock.acquire(sys._getframe().f_code.co_name)
623 try:
624
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
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
634 dp.mol.add_item(mol_name=mol_name, mol_type=mol_type)
635
636
637 mol = dp.mol[-1]
638
639
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
647 finally:
648 status.spin_lock.release(sys._getframe().f_code.co_name)
649
650
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
670 if pipe == None:
671 pipe = pipes.cdp_name()
672
673
674 check_pipe(pipe)
675
676
677 status.spin_lock.acquire(sys._getframe().f_code.co_name)
678 try:
679
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
685 mol_cont.res.add_item(res_num=res_num, res_name=res_name)
686
687
688 res = mol_cont.res[-1]
689
690
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
698 finally:
699 status.spin_lock.release(sys._getframe().f_code.co_name)
700
701
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
719 if pipe == None:
720 pipe = pipes.cdp_name()
721
722
723 check_pipe()
724
725
726 dp = pipes.get_pipe(pipe)
727
728
729 status.spin_lock.acquire(sys._getframe().f_code.co_name)
730 try:
731
732 mol_token, res_token, spin_token = tokenise(res_id)
733
734
735 if spin_token != None:
736 raise RelaxSpinSelectDisallowError
737
738
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
749 if averaging not in ['linear']:
750 raise RelaxError("The '%s' averaging technique is unknown." % averaging)
751
752
753 positions = []
754 for atom in members:
755
756 spin = return_spin(spin_id=atom, pipe=pipe)
757
758
759 if spin == None:
760 raise RelaxNoSpinError(atom)
761
762
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
767 pos = spin.pos
768
769
770 multi_model = True
771 if type(pos[0]) in [float, float64]:
772 multi_model = False
773 pos = [pos]
774
775
776 positions.append([])
777 for i in range(len(pos)):
778 positions[-1].append(pos[i].tolist())
779
780
781 for atom in members:
782
783 spin = return_spin(spin_id=atom, pipe=pipe)
784
785
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
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
798 spin.averaging = averaging
799 spin.members = members
800 if averaging == 'linear':
801
802 ave = linear_ave(positions)
803
804
805 if multi_model:
806 spin.pos = ave
807 else:
808 spin.pos = ave[0]
809
810
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
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
839 if pipe == None:
840 pipe = pipes.cdp_name()
841
842
843 check_pipe()
844
845
846 dp = pipes.get_pipe(pipe)
847
848
849 status.spin_lock.acquire(sys._getframe().f_code.co_name)
850 try:
851
852 new_spins = []
853
854
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
863 for i in range(len(dp.mol)):
864
865 if mol_index != None and mol_index != i:
866 continue
867
868
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
877 for j in range(len(dp.mol[i].res)):
878
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
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
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
896 spin_index = len(dp.mol[i].res[j].spin) - 1
897
898
899 new_spins.append(spin_cont)
900
901
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
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
913 finally:
914 status.spin_lock.release(sys._getframe().f_code.co_name)
915
916
917 return new_spins
918
919
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
932 if pipe == None:
933 pipe = pipes.cdp_name()
934
935
936 check_pipe(pipe)
937
938
939 spin_num = 0
940 for mol_index, res_index, spin_index in spin_index_loop(pipe=pipe):
941
942 if spin_num == global_index:
943 return mol_index, res_index, spin_index
944
945
946 spin_num = spin_num + 1
947
948
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
957 status.spin_lock.acquire(sys._getframe().f_code.co_name)
958 try:
959
960 mol_token, res_token, spin_token = tokenise(mol_id)
961
962
963 if spin_token != None:
964 raise RelaxSpinSelectDisallowError
965
966
967 if res_token != None:
968 raise RelaxResSelectDisallowError
969
970
971 molecules = parse_token(mol_token)
972
973
974 indices = []
975
976
977 for i in range(len(cdp.mol)):
978
979 if cdp.mol[i].name in molecules:
980 indices.append(i)
981
982
983 indices.reverse()
984
985
986 for index in indices:
987 metadata_prune(mol_index=index)
988
989
990 for index in indices:
991 cdp.mol.pop(index)
992
993
994 if len(cdp.mol) == 0:
995 cdp.mol.add_item()
996
997
998 metadata_update()
999
1000
1001 finally:
1002 status.spin_lock.release(sys._getframe().f_code.co_name)
1003
1004
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
1013 status.spin_lock.acquire(sys._getframe().f_code.co_name)
1014 try:
1015
1016 mol_token, res_token, spin_token = tokenise(res_id)
1017
1018
1019 if spin_token != None:
1020 raise RelaxSpinSelectDisallowError
1021
1022
1023 residues = parse_token(res_token)
1024
1025
1026 for mol in molecule_loop(res_id):
1027
1028 indices = []
1029
1030
1031 for i in range(len(mol.res)):
1032
1033 if mol.res[i].num in residues or mol.res[i].name in residues:
1034 indices.append(i)
1035
1036
1037 indices.reverse()
1038
1039
1040 for index in indices:
1041 metadata_prune(mol_index=mol._mol_index, res_index=index)
1042
1043
1044 for index in indices:
1045 mol.res.pop(index)
1046
1047
1048 if len(mol.res) == 0:
1049 mol.res.add_item()
1050
1051
1052 metadata_update()
1053
1054
1055 finally:
1056 status.spin_lock.release(sys._getframe().f_code.co_name)
1057
1058
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
1067 status.spin_lock.acquire(sys._getframe().f_code.co_name)
1068 try:
1069
1070
1071 mol_token, res_token, spin_token = tokenise(spin_id)
1072
1073
1074 spins = parse_token(spin_token)
1075
1076
1077 for res in residue_loop(spin_id):
1078
1079 indices = []
1080
1081
1082 for i in range(len(res.spin)):
1083
1084 if res.spin[i].num in spins or res.spin[i].name in spins:
1085 indices.append(i)
1086
1087
1088 indices.reverse()
1089
1090
1091 for index in indices:
1092 metadata_prune(mol_index=res._mol_index, res_index=res._res_index, spin_index=index)
1093
1094
1095 for index in indices:
1096 res.spin.pop(index)
1097
1098
1099 if len(res.spin) == 0:
1100 res.spin.add_item(select=False)
1101
1102
1103 metadata_update()
1104
1105
1106 finally:
1107 status.spin_lock.release(sys._getframe().f_code.co_name)
1108
1109
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
1118 mol_token, res_token, spin_token = tokenise(mol_id)
1119
1120
1121 if res_token != None:
1122 raise RelaxResSelectDisallowError
1123 if spin_token != None:
1124 raise RelaxSpinSelectDisallowError
1125
1126
1127 if mol_token:
1128 mol_sel = '#' + mol_token
1129 else:
1130 mol_sel = None
1131
1132
1133 print("\n\n%-15s %-15s" % ("Molecule", "Number of residues"))
1134
1135
1136 for mol in molecule_loop(mol_sel):
1137
1138 print("%-15s %-15s" % (mol.name, repr(len(mol.res))))
1139
1140
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
1149 mol_token, res_token, spin_token = tokenise(res_id)
1150
1151
1152 if spin_token != None:
1153 raise RelaxSpinSelectDisallowError
1154
1155
1156 print("\n\n%-15s %-15s %-15s %-15s" % ("Molecule", "Res number", "Res name", "Number of spins"))
1157
1158
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
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
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
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
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
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
1189 if pipe == None:
1190 pipe = pipes.cdp_name()
1191
1192
1193 check_pipe(pipe)
1194
1195
1196 dp = pipes.get_pipe(pipe)
1197
1198
1199 if dp.mol.is_empty():
1200 return False
1201
1202
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
1220 if pipe == None:
1221 pipe = pipes.cdp_name()
1222
1223
1224 check_pipe(pipe)
1225
1226
1227 dp = pipes.get_pipe(pipe)
1228
1229
1230 select_obj = Selection(selection)
1231
1232
1233 global_i = -1
1234 mol_index = -1
1235
1236
1237 for mol in dp.mol:
1238
1239 mol_index = mol_index + 1
1240
1241
1242 res_index = -1
1243
1244
1245 for res in mol.res:
1246
1247 res_index = res_index + 1
1248
1249
1250 spin_index = -1
1251
1252
1253 for spin in res.spin:
1254
1255 spin_index = spin_index + 1
1256 global_i = global_i + 1
1257
1258
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
1261 if global_index:
1262 return global_i
1263 else:
1264 return mol_index, res_index, spin_index
1265
1266
1268 """Determine the first residue number.
1269
1270 @return: The number of the first residue.
1271 @rtype: int
1272 """
1273
1274
1275 mol = return_molecule(selection)
1276
1277
1278 return mol.res[0].num
1279
1280
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
1374 if pipe_cont == None:
1375 pipe_cont = pipes.get_pipe(pipe_name)
1376
1377
1378 id = ""
1379
1380
1381 if mol_name != None:
1382 id = id + "#" + mol_name
1383
1384
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
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
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
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
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
1468 id = ""
1469
1470
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
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
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
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
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
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
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
1573 if pipe_cont == None:
1574 pipe_cont = pipes.get_pipe(pipe_name)
1575
1576
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
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
1603 return pipe_cont, mol, res, spin, mol_name, res_num, res_name, spin_num, spin_name
1604
1605
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
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
1625 if mol_name == None:
1626 mol_name_s = ""
1627 else:
1628 mol_name_s = "%s "%mol_name
1629
1630
1631 if res_num == None:
1632 res_num_s = ""
1633 else:
1634 res_num_s = "%s"%res_num
1635
1636
1637 if res_name == None:
1638 res_name_s = ""
1639 else:
1640 res_name_s = "%s "%res_name
1641
1642
1643 if spin_num == None:
1644 spin_num_s = ""
1645 else:
1646 spin_num_s = "%s "%spin_name
1647
1648
1649 if spin_name == None:
1650 spin_name_s = ""
1651 else:
1652 spin_name_s = "@%s"%spin_name
1653
1654
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
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
1670 if not pipes.cdp_name():
1671 return []
1672
1673
1674 mol_ids = []
1675 for mol, mol_id in molecule_loop(selection, return_id=True):
1676 mol_ids.append(mol_id)
1677
1678
1679 return mol_ids
1680
1681
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
1692 if not pipes.cdp_name():
1693 return []
1694
1695
1696 mol_names = []
1697 for mol in molecule_loop(selection):
1698 mol_names.append(mol.name)
1699
1700
1701 return mol_names
1702
1703
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
1714 if not pipes.cdp_name():
1715 return []
1716
1717
1718 res_ids = []
1719 for res, res_id in residue_loop(selection, return_id=True):
1720 res_ids.append(res_id)
1721
1722
1723 return res_ids
1724
1725
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
1736 if not pipes.cdp_name():
1737 return []
1738
1739
1740 res_names = []
1741 for res in residue_loop(selection):
1742 res_names.append(res.name)
1743
1744
1745 return res_names
1746
1747
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
1758 if not pipes.cdp_name():
1759 return []
1760
1761
1762 res_nums = []
1763 for res in residue_loop(selection):
1764 res_nums.append(res.num)
1765
1766
1767 return res_nums
1768
1769
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
1780 if not pipes.cdp_name():
1781 return []
1782
1783
1784 spin_ids = []
1785 for spin, spin_id in spin_loop(selection, return_id=True):
1786 spin_ids.append(spin_id)
1787
1788
1789 return spin_ids
1790
1791
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
1802 if hasattr(spin, 'members'):
1803 return True
1804
1805
1806 return False
1807
1808
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
1821 if pipe == None:
1822 pipe = pipes.cdp_name()
1823
1824
1825 check_pipe(pipe)
1826
1827
1828 dp = pipes.get_pipe(pipe)
1829
1830
1831 if mol_name == None and len(dp.mol) == 1:
1832 return 0
1833
1834
1835 i = 0
1836 for mol in dp.mol:
1837
1838 if mol.name == mol_name:
1839 return i
1840
1841
1842 i += 1
1843
1844
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
1864 if pipe == None:
1865 pipe = pipes.cdp_name()
1866
1867
1868 check_pipe(pipe)
1869
1870
1871 dp = pipes.get_pipe(pipe)
1872
1873
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
1878 i = 0
1879 for res in dp.mol[mol_index].res:
1880
1881 if res_num != None and res.num == res_num:
1882 return i
1883
1884
1885 if res_num == None and res_name != None and res.name == res_name:
1886 return i
1887
1888
1889 i += 1
1890
1891
1892 return None
1893
1894
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
1905 mol = return_molecule(selection)
1906
1907
1908 return mol.res[-1].num
1909
1910
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
1921 ave = []
1922 for model_index in range(len(positions[0])):
1923
1924 ave.append(array([0.0, 0.0, 0.0]))
1925
1926
1927 for coord_index in range(3):
1928
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
1933 ave[model_index][coord_index] = ave[model_index][coord_index] / len(positions)
1934
1935
1936 return ave
1937
1938
2009
2010
2116
2117
2192
2193
2281
2282
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
2297 if pipe == None:
2298 pipe = pipes.cdp_name()
2299
2300
2301 check_pipe(pipe)
2302
2303
2304 dp = pipes.get_pipe(pipe)
2305
2306
2307 if not exists_mol_res_spin_data(pipe=pipe):
2308 return
2309
2310
2311 select_obj = Selection(selection)
2312
2313
2314 for mol in dp.mol:
2315
2316 if not select_obj.contains_mol(mol.name):
2317 continue
2318
2319
2320 if return_id:
2321 mol_id = generate_spin_id(pipe_cont=dp, mol_name=mol.name)
2322
2323
2324 if return_id:
2325 yield mol, mol_id
2326 else:
2327 yield mol
2328
2329
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
2342 status.spin_lock.acquire(sys._getframe().f_code.co_name)
2343 try:
2344
2345
2346 mol = return_molecule(mol_id)
2347
2348
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
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
2363 metadata_cleanup(mol_index=mol._mol_index)
2364 metadata_update(mol_index=mol._mol_index)
2365
2366
2367 finally:
2368 status.spin_lock.release(sys._getframe().f_code.co_name)
2369
2370
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
2383 status.spin_lock.acquire(sys._getframe().f_code.co_name)
2384 try:
2385
2386 select_obj = Selection(res_id)
2387 if select_obj.has_spins():
2388 raise RelaxSpinSelectDisallowError
2389
2390
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
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
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
2422 if pipe == None:
2423 pipe = pipes.cdp_name()
2424
2425
2426 check_pipe(pipe)
2427
2428
2429 status.spin_lock.acquire(sys._getframe().f_code.co_name)
2430 try:
2431
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
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
2447 finally:
2448 status.spin_lock.release(sys._getframe().f_code.co_name)
2449
2450
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
2463 status.spin_lock.acquire(sys._getframe().f_code.co_name)
2464 try:
2465
2466 i = 0
2467 for res in residue_loop(res_id):
2468 i = i + 1
2469
2470
2471 if i > 1:
2472 raise RelaxError("The numbering of multiple residues is disallowed, each residue requires a unique number.")
2473
2474
2475 select_obj = Selection(res_id)
2476 if select_obj.has_spins():
2477 raise RelaxSpinSelectDisallowError
2478
2479
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
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
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
2507 status.spin_lock.acquire(sys._getframe().f_code.co_name)
2508 try:
2509
2510 i = 0
2511 for spin in spin_loop(spin_id):
2512 i = i + 1
2513
2514
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
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
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
2530 finally:
2531 status.spin_lock.release(sys._getframe().f_code.co_name)
2532
2533
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
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
2571 seq = ''
2572 for res in res_names:
2573
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
2582 if not match:
2583 seq = seq + 'X'
2584
2585
2586 return seq
2587
2588
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
2601 if not hasattr(spin, 'members'):
2602 return
2603
2604
2605 for spin_id in spin.members:
2606
2607 spin = return_spin(spin_id=spin_id)
2608
2609
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
2632 if pipe == None:
2633 pipe = pipes.cdp_name()
2634
2635
2636 check_pipe(pipe)
2637
2638
2639 dp = pipes.get_pipe(pipe)
2640
2641
2642 if not exists_mol_res_spin_data(pipe=pipe):
2643 return
2644
2645
2646 select_obj = Selection(selection)
2647
2648
2649 for mol in dp.mol:
2650
2651 for res in mol.res:
2652
2653 if not select_obj.contains_res(res_num=res.num, res_name=res.name, mol=mol.name):
2654 continue
2655
2656
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
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
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
2683 if pipe == None:
2684 pipe = pipes.cdp_name()
2685
2686
2687 check_pipe(pipe)
2688
2689
2690 dp = pipes.get_pipe(pipe)
2691
2692
2693 select_obj = Selection(selection)
2694
2695
2696 mol_num = 0
2697 mol_container = None
2698 for mol in dp.mol:
2699
2700 if not select_obj.contains_mol(mol=mol.name):
2701 continue
2702
2703
2704 if selection == None and mol.name != None:
2705 continue
2706
2707
2708 mol_container = mol
2709
2710
2711 mol_num = mol_num + 1
2712
2713
2714 if mol_num > 1:
2715 raise RelaxMultiMolIDError(selection)
2716
2717
2718 return mol_container
2719
2720
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
2735 if pipe_cont == None:
2736 pipe_cont = pipes.get_pipe(pipe)
2737
2738
2739 if mol_name == None:
2740
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
2745 return pipe_cont.mol[0]
2746
2747
2748 for mol in pipe_cont.mol:
2749
2750 if mol.name == mol_name:
2751 return mol
2752
2753
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
2766 if pipe == None:
2767 pipe = pipes.cdp_name()
2768
2769
2770 check_pipe(pipe)
2771
2772
2773 dp = pipes.get_pipe(pipe)
2774
2775
2776 select_obj = Selection(selection)
2777
2778
2779 res = None
2780 res_num = 0
2781 res_container = None
2782 for i in range(len(dp.mol)):
2783
2784 if not select_obj.contains_mol(mol=dp.mol[i].name):
2785 continue
2786
2787
2788 mol_index = i
2789
2790
2791 for j in range(len(dp.mol[i].res)):
2792
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
2797 res_container = dp.mol[i].res[j]
2798 res_index = j
2799
2800
2801 res_num = res_num + 1
2802
2803
2804 if res_num > 1:
2805 raise RelaxMultiResIDError(selection)
2806
2807
2808 if indices:
2809 return res_container, mol_index, res_index
2810 else:
2811 return res_container
2812
2813
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
2828 if res_name == None and res_num == None:
2829
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
2834 return mol.res[0]
2835
2836
2837 for res in mol.res:
2838
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
2868 if pipe == None:
2869 pipe = pipes.cdp_name()
2870
2871
2872 dp = pipes.get_pipe(pipe)
2873
2874
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
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
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
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
2911 if spin_name == None and spin_num == None:
2912
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
2917 return res.spin[0]
2918
2919
2920 for spin in res.spin:
2921
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
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
2952 if is_unicode(selection):
2953 selection = str(selection)
2954
2955
2956 if pipe == None:
2957 pipe = pipes.cdp_name()
2958
2959
2960 dp = pipes.get_pipe(pipe)
2961
2962
2963 select_obj = Selection(selection)
2964
2965
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
2974 if not select_obj.contains_mol(mol=mol.name):
2975 continue
2976
2977
2978 for res in mol.res:
2979
2980 if not select_obj.contains_res(res_num=res.num, res_name=res.name, mol=mol.name):
2981 continue
2982
2983
2984 for spin in res.spin:
2985
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
2990 mol_names.append(mol.name)
2991 res_nums.append(res.num)
2992 res_names.append(res.name)
2993 spins.append(spin)
2994
2995
2996 spin_num = spin_num + 1
2997
2998
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
3002 if not multi and spin_num > 1:
3003 raise RelaxMultiSpinIDError(selection, spin_ids)
3004
3005
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
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
3032 if pipe == None:
3033 pipe = pipes.cdp_name()
3034
3035
3036 check_pipe(pipe)
3037
3038
3039 spin_num = 0
3040 for spin, mol_name, res_num, res_name in spin_loop(full_info=True, pipe=pipe):
3041
3042 if spin_num == global_index:
3043
3044 if return_spin_id:
3045
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
3049 return spin, spin_id
3050
3051
3052 else:
3053 return spin
3054
3055
3056 spin_num = spin_num + 1
3057
3058
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
3073 if pipe == None:
3074 pipe = pipes.cdp_name()
3075
3076
3077 dp = pipes.get_pipe(pipe)
3078
3079
3080 if not spin_hash and spin_id not in dp.mol._spin_id_lookup:
3081
3082 select_obj = Selection(spin_id)
3083
3084
3085 for i in range(len(dp.mol)):
3086
3087 if not select_obj.contains_mol(mol=dp.mol[i].name):
3088 continue
3089
3090
3091 mol_index = i
3092
3093
3094 for j in range(len(dp.mol[i].res)):
3095
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
3100 res_index = j
3101
3102
3103 for k in range(len(dp.mol[i].res[j].spin)):
3104
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
3109 spin_index = k
3110
3111
3112 break
3113
3114
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
3121 return mol_index, res_index, spin_index
3122
3123
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
3134 molecule_info = parse_token(molecule_token)
3135
3136
3137 mol_name = None
3138 for info in molecule_info:
3139
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
3146 if mol_name != None and not isinstance(mol_name, str):
3147 mol_name = str(mol_name)
3148
3149
3150 return mol_name
3151
3152
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
3163 residue_info = parse_token(residue_token)
3164
3165
3166 res_num = None
3167 res_name = None
3168 for info in residue_info:
3169
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
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
3184 return res_num, res_name
3185
3186
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
3197 spin_info = parse_token(spin_token)
3198
3199
3200 spin_num = None
3201 spin_name = None
3202 for info in spin_info:
3203
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
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
3218 return spin_num, spin_name
3219
3220
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
3233 check_pipe(pipe1)
3234 check_pipe(pipe2)
3235
3236
3237 pipe1 = pipes.get_pipe(pipe1)
3238 pipe2 = pipes.get_pipe(pipe2)
3239
3240
3241 if len(pipe1.mol) != len(pipe2.mol):
3242 return False
3243
3244
3245 for i in range(len(pipe1.mol)):
3246
3247 if len(pipe1.mol[i].res) != len(pipe2.mol[i].res):
3248 return False
3249
3250
3251 for j in range(len(pipe1.mol[i].res)):
3252
3253 if len(pipe1.mol[i].res[j].spin) != len(pipe2.mol[i].res[j].spin):
3254 return False
3255
3256
3257 for k in range(len(pipe1.mol[i].res[j].spin)):
3258
3259 if pipe1.mol[i].res[j].spin[k].num != pipe2.mol[i].res[j].spin[k].num:
3260 return False
3261
3262
3263 if pipe1.mol[i].res[j].spin[k].name != pipe2.mol[i].res[j].spin[k].name:
3264 return False
3265
3266
3267 return True
3268
3269
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
3284 valid_names = ['H',
3285 'C',
3286 'N',
3287 'O',
3288 'F',
3289 'Na',
3290 'P',
3291 'Cd'
3292 ]
3293
3294
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
3299 if pipe == None:
3300 pipe = pipes.cdp_name()
3301
3302
3303 check_pipe(pipe)
3304
3305
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
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
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
3341 if isotope not in supported_types:
3342 raise RelaxError("The nuclear isotope type '%s' is currently not supported." % isotope)
3343
3344
3345 if pipe == None:
3346 pipe = pipes.cdp_name()
3347
3348
3349 check_pipe(pipe)
3350
3351
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
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
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
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
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
3423 if mol.name != None:
3424
3425 if res.name != None:
3426
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
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
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
3439 if res.num != None:
3440
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
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
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
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
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
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
3465 if res.name != None:
3466
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
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
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
3479 if res.num != None:
3480
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
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
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
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
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
3501 return spin_ids
3502
3503
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
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
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
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
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
3565 if mol.name != None:
3566
3567 if res.name != None:
3568
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
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
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
3581 if res.num != None:
3582
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
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
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
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
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
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
3607 if res.name != None:
3608
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
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
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
3621 if res.num != None:
3622
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
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
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
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
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
3643 return spin_ids
3644
3645
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
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
3671 if mol.name != None:
3672
3673 if res.name != None:
3674
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
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
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
3687 if res.num != None:
3688
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
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
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
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
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
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
3713 if res.name != None:
3714
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
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
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
3727 if res.num != None:
3728
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
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
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
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
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
3749 return spin_ids
3750
3751
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
3764 if pipe == None:
3765 pipe = pipes.cdp_name()
3766
3767
3768 check_pipe(pipe)
3769
3770
3771 dp = pipes.get_pipe(pipe)
3772
3773
3774 if not exists_mol_res_spin_data(pipe=pipe):
3775 return
3776
3777
3778 select_obj = Selection(selection)
3779
3780
3781 for mol_index in range(len(dp.mol)):
3782
3783 mol = dp.mol[mol_index]
3784
3785
3786 for res_index in range(len(dp.mol[mol_index].res)):
3787
3788 res = dp.mol[mol_index].res[res_index]
3789
3790
3791 for spin_index in range(len(dp.mol[mol_index].res[res_index].spin)):
3792
3793 spin = dp.mol[mol_index].res[res_index].spin[spin_index]
3794
3795
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
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
3821 if pipe == None:
3822 pipe = pipes.cdp_name()
3823
3824
3825 check_pipe(pipe)
3826
3827
3828 dp = pipes.get_pipe(pipe)
3829
3830
3831 if not exists_mol_res_spin_data(pipe=pipe):
3832 return
3833
3834
3835 select_obj = Selection(selection)
3836
3837
3838 for mol in dp.mol:
3839
3840 for res in mol.res:
3841
3842 for spin in res.spin:
3843
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
3848 if skip_desel and not spin.select:
3849 continue
3850
3851
3852 if return_id:
3853 spin_id = generate_spin_id_unique(pipe_cont=dp, mol=mol, res=res, spin=spin)
3854
3855
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
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
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
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
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