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