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