1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 """The molecule-residue-spin containers."""
25
26
27 import numpy
28 from re import match
29 from string import lower
30
31
32 from float import floatAsByteArray
33 import generic_fns
34 from prototype import Prototype
35 from relax_errors import RelaxError, RelaxFromXMLNotEmptyError, RelaxImplementError
36 from relax_xml import fill_object_contents, object_to_xml, xml_to_object
37 import specific_fns
38
39
40
41
42
44 """Class containing all the spin system specific data."""
45
46 - def __init__(self, spin_name=None, spin_num=None, select=True):
47 """Set up the default objects of the spin system data container."""
48
49
50 self.name = spin_name
51 self.num = spin_num
52 self.select = select
53
54
56 """The string representation of the object.
57
58 Rather than using the standard Python conventions (either the string representation of the
59 value or the "<...desc...>" notation), a rich-formatted description of the object is given.
60 """
61
62
63 text = "Class containing all the spin system specific data.\n\n"
64
65
66 text = text + "\n"
67 text = text + "Objects:\n"
68 for name in dir(self):
69
70 if name == 'is_empty':
71 continue
72
73
74 if match("^_", name):
75 continue
76
77
78 text = text + " " + name + ": " + repr(getattr(self, name)) + "\n"
79
80 return text
81
82
84 """Method for converting old spin data structures to the new ones.
85
86 @keyword file_version: The relax XML version of the XML file.
87 @type file_version: int
88 """
89
90
91 self._back_compat_hook_mf_data()
92
93
94 self._back_compat_hook_ri_data()
95
96
98 """Converting the old model-free parameter vector to the new one."""
99
100
101 if not hasattr(self, 'params'):
102 return
103
104
105 for i in range(len(self.params)):
106 self.params[i] = lower(self.params[i])
107
108
110 """Converting the old spin relaxation data structures to the new ones."""
111
112
113 if not (hasattr(self, 'frq_labels') and hasattr(self, 'noe_r1_table') and hasattr(self, 'remap_table')):
114 return
115
116
117 self.ri_data = {}
118 self.ri_data_err = {}
119 sims = False
120 if hasattr(self, 'relax_sim_data'):
121 sims = True
122 self.ri_data_sim = {}
123
124
125 for i in range(self.num_ri):
126
127 ri_id = "%s_%s" % (self.ri_labels[i], self.frq_labels[self.remap_table[i]])
128
129
130 self.ri_data[ri_id] = self.relax_data[i]
131 self.ri_data_err[ri_id] = self.relax_error[i]
132
133
134 if sims:
135 self.ri_data_sim[ri_id] = []
136 for j in range(cdp.sim_number):
137 self.ri_data_sim[ri_id].append(self.relax_sim_data[j][i])
138
139
140 del self.frq
141 del self.frq_labels
142 del self.noe_r1_table
143 del self.num_frq
144 del self.num_ri
145 del self.ri_labels
146 del self.remap_table
147 del self.relax_data
148 del self.relax_error
149 if sims:
150 del self.relax_sim_data
151
152
154 """Method for testing if this SpinContainer object is empty.
155
156 @return: True if this container is empty and the spin number and name have not been set,
157 False otherwise.
158 @rtype: bool
159 """
160
161
162 if self.num != None or self.name != None:
163 return False
164
165
166 for name in dir(self):
167
168 if name == 'num' or name == 'name' or name == 'select':
169 continue
170
171
172 if name == 'is_empty':
173 continue
174
175
176 if match("^_", name):
177 continue
178
179
180 return False
181
182
183 return True
184
185
187 """List type data container for spin system specific data."""
188
190 """Set up the first spin system data container."""
191
192
193 self.append(SpinContainer())
194
195
197 """The string representation of the object.
198
199 Rather than using the standard Python conventions (either the string representation of the
200 value or the "<...desc...>" notation), a rich-formatted description of the object is given.
201 """
202
203
204 text = "Spin systems.\n\n"
205
206
207 text = text + "%-8s%-8s%-8s%-10s" % ("Index", "Number", "Name", "Selected") + "\n"
208 for i in xrange(len(self)):
209 text = text + "%-8i%-8s%-8s%-10s" % (i, repr(self[i].num), self[i].name, self[i].select) + "\n"
210 text = text + "\nThese can be accessed by typing 'D.mol[i].res[j].spin[k]', where D is the relax data storage object.\n"
211
212 return text
213
214
215 - def add_item(self, spin_name=None, spin_num=None, select=True):
216 """Function for appending an empty container to the list."""
217
218
219 if self.is_empty():
220 self[0].num = spin_num
221 self[0].name = spin_name
222 self[0].select = select
223
224
225 else:
226
227 for i in xrange(len(self)):
228
229 if spin_num != None:
230 if self[i].num == spin_num:
231 raise RelaxError("The spin number '" + repr(spin_num) + "' already exists.")
232
233
234 else:
235 if self[i].name == spin_name:
236 raise RelaxError("The unnumbered spin name '" + repr(spin_name) + "' already exists.")
237
238
239 self.append(SpinContainer(spin_name, spin_num, select))
240
241
243 """Method for testing if this SpinList object is empty.
244
245 @return: True if this list only has one SpinContainer and the spin number and name have
246 not been set, False otherwise.
247 @rtype: bool
248 """
249
250
251 if len(self) == 1 and self[0].is_empty():
252 return True
253
254
255 return False
256
257
258 - def from_xml(self, spin_nodes, file_version=None):
259 """Recreate a spin list data structure from the XML spin nodes.
260
261 @param spin_nodes: The spin XML nodes.
262 @type spin_nodes: xml.dom.minicompat.NodeList instance
263 @keyword file_version: The relax XML version of the XML file.
264 @type file_version: int
265 """
266
267
268 if not self.is_empty():
269 raise RelaxFromXMLNotEmptyError(self.__class__.__name__)
270
271
272 for spin_node in spin_nodes:
273
274 name = str(spin_node.getAttribute('name'))
275 if name == 'None':
276 name = None
277 num = eval(spin_node.getAttribute('num'))
278 self.add_item(spin_name=name, spin_num=num)
279
280
281 xml_to_object(spin_node, self[-1], file_version=file_version)
282
283
284 self[-1]._back_compat_hook(file_version)
285
286
287 - def to_xml(self, doc, element):
288 """Create XML elements for each spin.
289
290 @param doc: The XML document object.
291 @type doc: xml.dom.minidom.Document instance
292 @param element: The element to add the spin XML elements to.
293 @type element: XML element object
294 """
295
296
297 data_names = specific_fns.setup.get_specific_fn('data_names', generic_fns.pipes.get_type(), raise_error=False)
298 return_data_desc = specific_fns.setup.get_specific_fn('return_data_desc', generic_fns.pipes.get_type(), raise_error=False)
299
300
301 for i in xrange(len(self)):
302
303 spin_element = doc.createElement('spin')
304 element.appendChild(spin_element)
305
306
307 spin_element.setAttribute('desc', 'Spin container')
308 spin_element.setAttribute('name', str(self[i].name))
309 spin_element.setAttribute('num', str(self[i].num))
310
311
312 object_info = []
313 try:
314 for name in data_names(error_names=True, sim_names=True):
315
316 if return_data_desc:
317 desc = return_data_desc(name)
318 else:
319 desc = None
320
321
322 object_info.append([name, desc])
323 except RelaxImplementError:
324 pass
325
326
327 blacklist = []
328 for name, desc in object_info:
329
330 blacklist.append(name)
331
332
333 if not hasattr(self[i], name):
334 continue
335
336
337 sub_element = doc.createElement(name)
338 spin_element.appendChild(sub_element)
339
340
341 if desc:
342 sub_element.setAttribute('desc', desc)
343
344
345 object = getattr(self[i], name)
346
347
348 object_to_xml(doc, sub_element, value=object)
349
350
351 fill_object_contents(doc, spin_element, object=self[i], blacklist=['name', 'num', 'spin'] + blacklist + list(self[i].__class__.__dict__.keys()))
352
353
354
355
356
357
359 """Class containing all the residue specific data."""
360
361 - def __init__(self, res_name=None, res_num=None):
362 """Set up the default objects of the residue data container."""
363
364
365 self.name = res_name
366 self.num = res_num
367
368
369 self.spin = SpinList()
370
371
373 """The string representation of the object.
374
375 Rather than using the standard Python conventions (either the string representation of the
376 value or the "<...desc...>" notation), a rich-formatted description of the object is given.
377 """
378
379
380 text = "Class containing all the residue specific data.\n"
381
382
383 text = text + "\n"
384 text = text + "Objects:\n"
385 for name in dir(self):
386
387 if name == 'spin':
388 text = text + " spin: The list of spin systems of the residues\n"
389 continue
390
391
392 if name == 'is_empty':
393 continue
394
395
396 if match("^_", name):
397 continue
398
399
400 text = text + " " + name + ": " + repr(getattr(self, name)) + "\n"
401
402 return text
403
404
406 """Method for testing if this ResidueContainer object is empty.
407
408 @return: True if this container is empty and the residue number and name have not been
409 set, False otherwise.
410 @rtype: bool
411 """
412
413
414 if self.num != None or self.name != None:
415 return False
416
417
418 for name in dir(self):
419
420 if name == 'num' or name == 'name' or name == 'spin':
421 continue
422
423
424 if name == 'is_empty':
425 continue
426
427
428 if match("^_", name):
429 continue
430
431
432 return False
433
434
435 if not self.spin.is_empty():
436 return False
437
438
439 return True
440
441
443 """List type data container for residue specific data."""
444
450
451
453 """The string representation of the object.
454
455 Rather than using the standard Python conventions (either the string representation of the
456 value or the "<...desc...>" notation), a rich-formatted description of the object is given.
457 """
458
459
460 text = "Residues.\n\n"
461
462
463 text = text + "%-8s%-8s%-8s" % ("Index", "Number", "Name") + "\n"
464 for i in xrange(len(self)):
465 text = text + "%-8i%-8s%-8s" % (i, repr(self[i].num), self[i].name) + "\n"
466 text = text + "\nThese can be accessed by typing 'D.mol[i].res[j]', where D is the relax data storage object.\n"
467
468 return text
469
470
471 - def add_item(self, res_name=None, res_num=None):
472 """Append an empty ResidueContainer to the ResidueList."""
473
474
475 if self.is_empty():
476 self[0].num = res_num
477 self[0].name = res_name
478
479
480 else:
481
482 for i in xrange(len(self)):
483
484 if res_num != None:
485 if self[i].num == res_num:
486 raise RelaxError("The residue number '" + repr(res_num) + "' already exists in the sequence.")
487
488
489 else:
490 if self[i].name == res_name:
491 raise RelaxError("The unnumbered residue name '" + repr(res_name) + "' already exists.")
492
493
494 self.append(ResidueContainer(res_name, res_num))
495
496
498 """Method for testing if this ResidueList object is empty.
499
500 @return: True if this list only has one ResidueContainer and the residue number and name
501 have not been set, False otherwise.
502 @rtype: bool
503 """
504
505
506 if len(self) == 1 and self[0].is_empty():
507 return True
508
509
510 return False
511
512
513 - def from_xml(self, res_nodes, file_version=None):
514 """Recreate a residue list data structure from the XML residue nodes.
515
516 @param res_nodes: The residue XML nodes.
517 @type res_nodes: xml.dom.minicompat.NodeList instance
518 @keyword file_version: The relax XML version of the XML file.
519 @type file_version: int
520 """
521
522
523 if not self.is_empty():
524 raise RelaxFromXMLNotEmptyError(self.__class__.__name__)
525
526
527 for res_node in res_nodes:
528
529 name = str(res_node.getAttribute('name'))
530 if name == 'None':
531 name = None
532 num = eval(res_node.getAttribute('num'))
533 self.add_item(res_name=name, res_num=num)
534
535
536 spin_nodes = res_node.getElementsByTagName('spin')
537
538
539 self[-1].spin.from_xml(spin_nodes, file_version=file_version)
540
541
542 - def to_xml(self, doc, element):
543 """Create XML elements for each residue.
544
545 @param doc: The XML document object.
546 @type doc: xml.dom.minidom.Document instance
547 @param element: The element to add the residue XML elements to.
548 @type element: XML element object
549 """
550
551
552 for i in xrange(len(self)):
553
554 res_element = doc.createElement('res')
555 element.appendChild(res_element)
556
557
558 res_element.setAttribute('desc', 'Residue container')
559 res_element.setAttribute('name', str(self[i].name))
560 res_element.setAttribute('num', str(self[i].num))
561
562
563 fill_object_contents(doc, res_element, object=self[i], blacklist=['name', 'num', 'spin'] + list(self[i].__class__.__dict__.keys()))
564
565
566 self[i].spin.to_xml(doc, res_element)
567
568
569
570
571
572
574 """Class containing all the molecule specific data."""
575
576 - def __init__(self, mol_name=None, mol_type=None):
577 """Set up the default objects of the molecule data container."""
578
579
580 self.name = mol_name
581
582
583 self.type = mol_type
584
585
586 self.res = ResidueList()
587
588
590 """The string representation of the object.
591
592 Rather than using the standard Python conventions (either the string representation of the
593 value or the "<...desc...>" notation), a rich-formatted description of the object is given.
594 """
595
596
597 text = "Class containing all the molecule specific data.\n"
598
599
600 text = text + "\n"
601 text = text + "Objects:\n"
602 for name in dir(self):
603
604 if name == 'res':
605 text = text + " res: The list of the residues of the molecule\n"
606 continue
607
608
609 if name == 'is_empty':
610 continue
611
612
613 if match("^_", name):
614 continue
615
616
617 text = text + " " + name + ": " + repr(getattr(self, name)) + "\n"
618
619 return text
620
621
623 """Method for testing if this MoleculeContainer object is empty.
624
625 @return: True if this container is empty and the molecule name has not been set, False
626 otherwise.
627 @rtype: bool
628 """
629
630
631 if self.name != None:
632 return False
633
634
635 for name in dir(self):
636
637 if name in ['name', 'res', 'type']:
638 continue
639
640
641 if name == 'is_empty':
642 continue
643
644
645 if match("^_", name):
646 continue
647
648
649 return False
650
651
652 if not self.res.is_empty():
653 return False
654
655
656 return True
657
658
660 """List type data container for the molecule specific data."""
661
667
668
670 """The string representation of the object.
671
672 Rather than using the standard Python conventions (either the string representation of the
673 value or the "<...desc...>" notation), a rich-formatted description of the object is given.
674 """
675
676 text = "Molecules.\n\n"
677 text = text + "%-8s%-8s" % ("Index", "Name") + "\n"
678 for i in xrange(len(self)):
679 text = text + "%-8i%-8s" % (i, self[i].name) + "\n"
680 text = text + "\nThese can be accessed by typing 'D.mol[i]', where D is the relax data storage object.\n"
681 return text
682
683
684 - def add_item(self, mol_name=None, mol_type=None):
685 """Append an empty MoleculeContainer to the MoleculeList."""
686
687
688 if self.is_empty():
689 self[0].name = mol_name
690 self[0].type = mol_type
691
692
693 else:
694
695 for i in xrange(len(self)):
696 if self[i].name == mol_name:
697 raise RelaxError("The molecule '%s' already exists in the sequence." % mol_name)
698
699
700 self.append(MoleculeContainer(mol_name, mol_type))
701
702
704 """Method for testing if this MoleculeList object is empty.
705
706 @return: True if this list only has one MoleculeContainer and the molecule name has not
707 been set, False otherwise.
708 @rtype: bool
709 """
710
711
712 if len(self) == 1 and self[0].is_empty():
713 return True
714
715
716 return False
717
718
719 - def from_xml(self, mol_nodes, file_version=None):
720 """Recreate a molecule list data structure from the XML molecule nodes.
721
722 @param mol_nodes: The molecule XML nodes.
723 @type mol_nodes: xml.dom.minicompat.NodeList instance
724 @keyword file_version: The relax XML version of the XML file.
725 @type file_version: int
726 """
727
728
729 if not self.is_empty():
730 raise RelaxFromXMLNotEmptyError(self.__class__.__name__)
731
732
733 for mol_node in mol_nodes:
734
735 name = str(mol_node.getAttribute('name'))
736 if name == 'None':
737 name = None
738 type = str(mol_node.getAttribute('type'))
739 if type == 'None':
740 type = None
741 self.add_item(mol_name=name, mol_type=type)
742
743
744 res_nodes = mol_node.getElementsByTagName('res')
745
746
747 self[-1].res.from_xml(res_nodes, file_version=file_version)
748
749
750 - def to_xml(self, doc, element):
751 """Create XML elements for each molecule.
752
753 @param doc: The XML document object.
754 @type doc: xml.dom.minidom.Document instance
755 @param element: The element to add the molecule XML elements to.
756 @type element: XML element object
757 """
758
759
760 for i in xrange(len(self)):
761
762 mol_element = doc.createElement('mol')
763 element.appendChild(mol_element)
764
765
766 mol_element.setAttribute('desc', 'Molecule container')
767 mol_element.setAttribute('name', str(self[i].name))
768 mol_element.setAttribute('type', str(self[i].type))
769
770
771 fill_object_contents(doc, mol_element, object=self[i], blacklist=['name', 'res', 'type'] + list(self[i].__class__.__dict__.keys()))
772
773
774 self[i].res.to_xml(doc, mol_element)
775