1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 """The interatomic data containers of the relax data store."""
24
25
26 from re import match
27
28
29 import pipe_control
30 from data_store.prototype import Prototype
31 from data_store.relax_xml import fill_object_contents, object_to_xml, xml_to_object
32 from lib.errors import RelaxFromXMLNotEmptyError, RelaxImplementError
33 import specific_analyses
34
35
37 """Class containing the interatomic data."""
38
39 - def __init__(self, spin_id1=None, spin_id2=None, select=True):
40 """Set up the objects of the interatomic data container.
41
42 @keyword spin_id1: The spin ID string of the first atom.
43 @type spin_id1: str
44 @keyword spin_id2: The spin ID string of the second atom.
45 @type spin_id2: str
46 @keyword select: The selection flag.
47 @type select: bool
48 """
49
50
51 self.spin_id1 = spin_id1
52 self.spin_id2 = spin_id2
53
54
55 self.dipole_pair = False
56 self.select = select
57
58
60 """The string representation of the object.
61
62 Rather than using the standard Python conventions (either the string representation of the
63 value or the "<...desc...>" notation), a rich-formatted description of the object is given.
64 """
65
66
67 text = "Class containing all the interatomic specific data between spins %s and %s.\n\n" % (self.spin_id1, self.spin_id2)
68
69
70 text = text + "\n"
71 text = text + "Objects:\n"
72 for name in dir(self):
73
74 if name in ['is_empty']:
75 continue
76
77
78 if match("^_", name):
79 continue
80
81
82 text += " %s: %s\n" % (name, repr(getattr(self, name)))
83
84 return text
85
86
88 """Method for testing if this InteratomContainer object is empty.
89
90 @return: True if this container is empty, False otherwise.
91 @rtype: bool
92 """
93
94
95 for name in dir(self):
96
97 if name in ['dipole_pair', 'spin_id1', 'spin_id2', 'select']:
98 continue
99
100
101 if name in ['is_empty']:
102 continue
103
104
105 if match("^_", name):
106 continue
107
108
109 return False
110
111
112 return True
113
114
115
117 """List type data container for interatomic specific data."""
118
120 """The string representation of the object.
121
122 Rather than using the standard Python conventions (either the string representation of the value or the "<...desc...>" notation), a rich-formatted description of the object is given.
123 """
124
125
126 text = "Interatomic data.\n\n"
127
128
129 text += "%-25s%-25s%-25s" % ("Index", "Spin ID 1", "Spin ID 2") + "\n"
130 for i in range(len(self)):
131 text += "%-25i%-25s%-25s\n\n" % (i, self[i].spin_id1, self[i].spin_id2)
132
133 return text
134
135
136 - def add_item(self, spin_id1=None, spin_id2=None):
137 """Append an empty container to the list.
138
139 @keyword spin_id1: The spin ID string of the first atom.
140 @type spin_id1: str
141 @keyword spin_id2: The spin ID string of the first atom.
142 @type spin_id2: str
143 @return: The new interatomic data container.
144 @rtype: InteratomContainer instance
145 """
146
147
148 cont = InteratomContainer(spin_id1, spin_id2)
149 self.append(cont)
150
151
152 return cont
153
154
156 """Method for testing if this InteratomList object is empty.
157
158 @return: True if this list contains no InteratomContainers, False otherwise.
159 @rtype: bool
160 """
161
162
163 if len(self) == 0:
164 return True
165
166
167 return False
168
169
170 - def from_xml(self, interatom_nodes, file_version=None):
171 """Recreate an interatomic list data structure from the XML spin nodes.
172
173 @param interatom_nodes: The spin XML nodes.
174 @type interatom_nodes: xml.dom.minicompat.NodeList instance
175 @keyword file_version: The relax XML version of the XML file.
176 @type file_version: int
177 """
178
179
180 if not self.is_empty():
181 raise RelaxFromXMLNotEmptyError(self.__class__.__name__)
182
183
184 for interatom_node in interatom_nodes:
185
186 spin_id1 = str(interatom_node.getAttribute('spin_id1'))
187 spin_id2 = str(interatom_node.getAttribute('spin_id2'))
188 self.add_item(spin_id1=spin_id1, spin_id2=spin_id2)
189
190
191 xml_to_object(interatom_node, self[-1], file_version=file_version)
192
193
194 - def to_xml(self, doc, element):
195 """Create XML elements for each spin.
196
197 @param doc: The XML document object.
198 @type doc: xml.dom.minidom.Document instance
199 @param element: The element to add the spin XML elements to.
200 @type element: XML element object
201 """
202
203
204 data_names = specific_analyses.setup.get_specific_fn('data_names', pipe_control.pipes.get_type(), raise_error=False)
205 return_data_desc = specific_analyses.setup.get_specific_fn('return_data_desc', pipe_control.pipes.get_type(), raise_error=False)
206
207
208 for i in range(len(self)):
209
210 interatom_element = doc.createElement('interatomic')
211 element.appendChild(interatom_element)
212
213
214 interatom_element.setAttribute('desc', 'Interatomic data container')
215 interatom_element.setAttribute('spin_id1', str(self[i].spin_id1))
216 interatom_element.setAttribute('spin_id2', str(self[i].spin_id2))
217
218
219 object_info = []
220 try:
221 for name in data_names(error_names=True, sim_names=True):
222
223 if return_data_desc:
224 desc = return_data_desc(name)
225 else:
226 desc = None
227
228
229 object_info.append([name, desc])
230 except RelaxImplementError:
231 pass
232
233
234 blacklist = []
235 for name, desc in object_info:
236
237 blacklist.append(name)
238
239
240 if not hasattr(self[i], name):
241 continue
242
243
244 sub_element = doc.createElement(name)
245 interatom_element.appendChild(sub_element)
246
247
248 if desc:
249 sub_element.setAttribute('desc', desc)
250
251
252 object = getattr(self[i], name)
253
254
255 object_to_xml(doc, sub_element, value=object)
256
257
258 fill_object_contents(doc, interatom_element, object=self[i], blacklist=['spin_id1', 'spin_id2'] + blacklist + list(self[i].__class__.__dict__.keys()))
259