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, pipe_type=None):
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 @keyword pipe_type: The type of the pipe being converted to XML.
202 @type pipe_type: str
203 """
204
205
206 data_names = specific_analyses.setup.get_specific_fn('data_names', pipe_type, raise_error=False)
207 return_data_desc = specific_analyses.setup.get_specific_fn('return_data_desc', pipe_type, raise_error=False)
208
209
210 for i in range(len(self)):
211
212 interatom_element = doc.createElement('interatomic')
213 element.appendChild(interatom_element)
214
215
216 interatom_element.setAttribute('desc', 'Interatomic data container')
217 interatom_element.setAttribute('spin_id1', str(self[i].spin_id1))
218 interatom_element.setAttribute('spin_id2', str(self[i].spin_id2))
219
220
221 object_info = []
222 try:
223 for name in data_names(error_names=True, sim_names=True):
224
225 if return_data_desc:
226 desc = return_data_desc(name)
227 else:
228 desc = None
229
230
231 object_info.append([name, desc])
232 except RelaxImplementError:
233 pass
234
235
236 blacklist = []
237 for name, desc in object_info:
238
239 blacklist.append(name)
240
241
242 if not hasattr(self[i], name):
243 continue
244
245
246 sub_element = doc.createElement(name)
247 interatom_element.appendChild(sub_element)
248
249
250 if desc:
251 sub_element.setAttribute('desc', desc)
252
253
254 object = getattr(self[i], name)
255
256
257 object_to_xml(doc, sub_element, value=object)
258
259
260 fill_object_contents(doc, interatom_element, object=self[i], blacklist=['spin_id1', 'spin_id2'] + blacklist + list(self[i].__class__.__dict__.keys()))
261