1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 from re import match
25 from warnings import warn
26
27
28 from align_tensor import AlignTensorList
29 from diff_tensor import DiffTensorData
30 from exp_info import ExpInfo
31 import generic_fns
32 from mol_res_spin import MoleculeList
33 from prototype import Prototype
34 from relax_errors import RelaxFromXMLNotEmptyError
35 from relax_xml import fill_object_contents, node_value_to_python, xml_to_object
36 from relax_warnings import RelaxWarning
37
38
40 """Class containing all the program data."""
41
43 """Set up all the PipeContainer data structures."""
44
45
46 self.mol = MoleculeList()
47
48
49 self.pipe_type = None
50
51
52 self.hybrid_pipes = []
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 = "The data pipe storage object.\n"
64
65
66 spec_obj = ['exp_info', 'mol', 'diff_tensor', 'structure']
67
68
69 text = text + "\n"
70 text = text + "Objects:\n"
71 for name in dir(self):
72
73 if name == 'mol':
74 text = text + " mol: The molecule list (for the storage of the spin system specific data)\n"
75
76
77 if name == 'diff_tensor':
78 text = text + " diff_tensor: The Brownian rotational diffusion tensor data object\n"
79
80
81 if name == 'structure':
82 text = text + " structure: The 3D molecular data object\n"
83
84
85 if name == 'exp_info':
86 text = text + " exp_info: The data container for experimental information\n"
87
88
89 if name in list(self.__class__.__dict__.keys()):
90 continue
91
92
93 if match("^_", name) or name in spec_obj:
94 continue
95
96
97 text = text + " " + name + ": " + repr(getattr(self, name)) + "\n"
98
99
100 return text
101
102
104 """Method for converting old data structures to the new ones.
105
106 @keyword file_version: The relax XML version of the XML file.
107 @type file_version: int
108 """
109
110
111 self._back_compat_hook_ri_data()
112
113
115 """Converting the old relaxation data structures to the new ones."""
116
117
118 if not (hasattr(cdp, 'frq_labels') and hasattr(cdp, 'noe_r1_table') and hasattr(cdp, 'remap_table')):
119 return
120
121
122 cdp.ri_ids = []
123 cdp.ri_type = {}
124 frq = {}
125
126
127 for i in range(cdp.num_ri):
128
129 ri_id = "%s_%s" % (cdp.ri_labels[i], cdp.frq_labels[cdp.remap_table[i]])
130
131
132 if ri_id in cdp.ri_ids:
133
134 for j in range(100):
135
136 new_id = "%s_%s" % (ri_id, j)
137
138
139 if not new_id in cdp.ri_ids:
140 ri_id = new_id
141 break
142
143
144 cdp.ri_ids.append(ri_id)
145
146
147 cdp.ri_type[ri_id] = cdp.ri_labels[i]
148
149
150 frq[ri_id] = cdp.frq[cdp.remap_table[i]]
151
152
153 del cdp.frq
154 del cdp.frq_labels
155 del cdp.noe_r1_table
156 del cdp.num_frq
157 del cdp.num_ri
158 del cdp.remap_table
159 del cdp.ri_labels
160
161
162 cdp.frq = frq
163
164
165 - def from_xml(self, pipe_node, file_version=None, dir=None):
166 """Read a pipe container XML element and place the contents into this pipe.
167
168 @param pipe_node: The data pipe XML node.
169 @type pipe_node: xml.dom.minidom.Element instance
170 @keyword file_version: The relax XML version of the XML file.
171 @type file_version: int
172 @keyword dir: The name of the directory containing the results file (needed for loading external files).
173 @type dir: str
174 """
175
176
177 if not self.is_empty():
178 raise RelaxFromXMLNotEmptyError(self.__class__.__name__)
179
180
181 global_node = pipe_node.getElementsByTagName('global')[0]
182 xml_to_object(global_node, self, file_version=file_version)
183
184
185 self._back_compat_hook(file_version)
186
187
188 hybrid_node = pipe_node.getElementsByTagName('hybrid')[0]
189 pipes_node = hybrid_node.getElementsByTagName('pipes')[0]
190 setattr(self, 'hybrid_pipes', node_value_to_python(pipes_node.childNodes[0]))
191
192
193 exp_info_nodes = pipe_node.getElementsByTagName('exp_info')
194 if exp_info_nodes:
195
196 self.exp_info = ExpInfo()
197
198
199 self.exp_info.from_xml(exp_info_nodes[0], file_version=file_version)
200
201
202 diff_tensor_nodes = pipe_node.getElementsByTagName('diff_tensor')
203 if diff_tensor_nodes:
204
205 self.diff_tensor = DiffTensorData()
206
207
208 self.diff_tensor.from_xml(diff_tensor_nodes[0], file_version=file_version)
209
210
211 align_tensor_nodes = pipe_node.getElementsByTagName('align_tensors')
212 if align_tensor_nodes:
213
214 self.align_tensors = AlignTensorList()
215
216
217 self.align_tensors.from_xml(align_tensor_nodes[0], file_version=file_version)
218
219
220 mol_nodes = pipe_node.getElementsByTagName('mol')
221 self.mol.from_xml(mol_nodes, file_version=file_version)
222
223
224 str_nodes = pipe_node.getElementsByTagName('structure')
225 if str_nodes:
226
227 parser = str(str_nodes[0].getAttribute('id'))
228
229
230 fail = False
231 if parser == 'scientific':
232 self.structure = generic_fns.structure.scientific.Scientific_data()
233 elif parser == 'internal':
234 self.structure = generic_fns.structure.internal.Internal()
235 else:
236 warn(RelaxWarning("The structural file parser " + repr(parser) + " is unknown. The structure will not be loaded."))
237 fail = True
238
239
240 if not fail:
241 self.structure.from_xml(str_nodes[0], dir=dir, id=parser, file_version=file_version)
242
243
245 """Method for testing if the data pipe is empty.
246
247 @return: True if the data pipe is empty, False otherwise.
248 @rtype: bool
249 """
250
251
252 if hasattr(self, 'structure') and not self.structure.is_empty():
253 return False
254
255
256 if not self.mol.is_empty():
257 return False
258
259
260 if self.hybrid_pipes:
261 return False
262
263
264 for name in dir(self):
265
266 if name == 'mol' or name == 'pipe_type' or name == 'hybrid_pipes':
267 continue
268
269
270 if name in list(self.__class__.__dict__.keys()):
271 continue
272
273
274 if match("^_", name):
275 continue
276
277
278 return False
279
280
281 return True
282
283
284 - def to_xml(self, doc, element):
285 """Create a XML element for the current data pipe.
286
287 @param doc: The XML document object.
288 @type doc: xml.dom.minidom.Document instance
289 @param element: The XML element to add the pipe XML element to.
290 @type element: XML element object
291 """
292
293
294 global_element = doc.createElement('global')
295 element.appendChild(global_element)
296 global_element.setAttribute('desc', 'Global data located in the top level of the data pipe')
297 fill_object_contents(doc, global_element, object=self, blacklist=['align_tensors', 'diff_tensor', 'exp_info', 'hybrid_pipes', 'mol', 'pipe_type', 'structure'] + list(self.__class__.__dict__.keys()))
298
299
300 self.xml_create_hybrid_element(doc, element)
301
302
303 if hasattr(self, 'exp_info'):
304 self.exp_info.to_xml(doc, element)
305
306
307 if hasattr(self, 'diff_tensor'):
308 self.diff_tensor.to_xml(doc, element)
309
310
311 if hasattr(self, 'align_tensors'):
312 self.align_tensors.to_xml(doc, element)
313
314
315 self.mol.to_xml(doc, element)
316
317
318 if hasattr(self, 'structure'):
319 self.structure.to_xml(doc, element)
320
321
323 """Create an XML element for the data pipe hybridisation information.
324
325 @param doc: The XML document object.
326 @type doc: xml.dom.minidom.Document instance
327 @param element: The element to add the hybridisation info to.
328 @type element: XML element object
329 """
330
331
332 hybrid_element = doc.createElement('hybrid')
333 element.appendChild(hybrid_element)
334
335
336 hybrid_element.setAttribute('desc', 'Data pipe hybridisation information')
337
338
339 list_element = doc.createElement('pipes')
340 hybrid_element.appendChild(list_element)
341
342
343 text_val = doc.createTextNode(str(self.hybrid_pipes))
344 list_element.appendChild(text_val)
345