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