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 from data_store.prototype import Prototype
30 from lib.errors import RelaxFromXMLNotEmptyError, RelaxImplementError
31 from lib.xml import fill_object_contents, object_to_xml, xml_to_object
32 import specific_analyses
33
34
36 """Class containing the interatomic data."""
37
38 - def __init__(self, spin_id1=None, spin_id2=None, select=True):
39 """Set up the objects of the interatomic data container.
40
41 @keyword spin_id1: The spin ID string of the first atom.
42 @type spin_id1: str
43 @keyword spin_id2: The spin ID string of the second atom.
44 @type spin_id2: str
45 @keyword select: The selection flag.
46 @type select: bool
47 """
48
49
50 self.spin_id1 = spin_id1
51 self.spin_id2 = spin_id2
52
53
54 self.dipole_pair = False
55 self.select = select
56
57
59 """The string representation of the object.
60
61 Rather than using the standard Python conventions (either the string representation of the
62 value or the "<...desc...>" notation), a rich-formatted description of the object is given.
63 """
64
65
66 text = "Class containing all the interatomic specific data between spins %s and %s.\n\n" % (self.spin_id1, self.spin_id2)
67
68
69 text = text + "\n"
70 text = text + "Objects:\n"
71 for name in dir(self):
72
73 if name in ['is_empty']:
74 continue
75
76
77 if match("^_", name):
78 continue
79
80
81 text += " %s: %s\n" % (name, repr(getattr(self, name)))
82
83 return text
84
85
87 """Method for testing if this InteratomContainer object is empty.
88
89 @return: True if this container is empty, False otherwise.
90 @rtype: bool
91 """
92
93
94 for name in dir(self):
95
96 if name in ['dipole_pair', 'spin_id1', 'spin_id2', 'select']:
97 continue
98
99
100 if name in ['is_empty']:
101 continue
102
103
104 if match("^_", name):
105 continue
106
107
108 return False
109
110
111 return True
112
113
114
116 """List type data container for interatomic specific data."""
117
119 """The string representation of the object.
120
121 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.
122 """
123
124
125 text = "Interatomic data.\n\n"
126
127
128 text += "%-25s%-25s%-25s" % ("Index", "Spin ID 1", "Spin ID 2") + "\n"
129 for i in range(len(self)):
130 text += "%-25i%-25s%-25s\n\n" % (i, self[i].spin_id1, self[i].spin_id2)
131
132 return text
133
134
135 - def add_item(self, spin_id1=None, spin_id2=None):
136 """Append an empty container to the list.
137
138 @keyword spin_id1: The spin ID string of the first atom.
139 @type spin_id1: str
140 @keyword spin_id2: The spin ID string of the first atom.
141 @type spin_id2: str
142 @return: The new interatomic data container.
143 @rtype: InteratomContainer instance
144 """
145
146
147 cont = InteratomContainer(spin_id1, spin_id2)
148 self.append(cont)
149
150
151 return cont
152
153
155 """Method for testing if this InteratomList object is empty.
156
157 @return: True if this list contains no InteratomContainers, False otherwise.
158 @rtype: bool
159 """
160
161
162 if len(self) == 0:
163 return True
164
165
166 return False
167
168
169 - def from_xml(self, interatom_nodes, file_version=None):
170 """Recreate an interatomic list data structure from the XML spin nodes.
171
172 @param interatom_nodes: The spin XML nodes.
173 @type interatom_nodes: xml.dom.minicompat.NodeList instance
174 @keyword file_version: The relax XML version of the XML file.
175 @type file_version: int
176 """
177
178
179 if not self.is_empty():
180 raise RelaxFromXMLNotEmptyError(self.__class__.__name__)
181
182
183 for interatom_node in interatom_nodes:
184
185 spin_id1 = str(interatom_node.getAttribute('spin_id1'))
186 spin_id2 = str(interatom_node.getAttribute('spin_id2'))
187 self.add_item(spin_id1=spin_id1, spin_id2=spin_id2)
188
189
190 xml_to_object(interatom_node, self[-1], file_version=file_version)
191
192
193 - def to_xml(self, doc, element, pipe_type=None):
194 """Create XML elements for each spin.
195
196 @param doc: The XML document object.
197 @type doc: xml.dom.minidom.Document instance
198 @param element: The element to add the spin XML elements to.
199 @type element: XML element object
200 @keyword pipe_type: The type of the pipe being converted to XML.
201 @type pipe_type: str
202 """
203
204
205 api = specific_analyses.api.return_api(analysis_type=pipe_type)
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 api.data_names(error_names=True, sim_names=True):
222
223 if hasattr(api, 'return_data_desc'):
224 desc = api.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