Package data_store :: Module interatomic
[hide private]
[frames] | no frames]

Source Code for Module data_store.interatomic

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2007-2014 Edward d'Auvergne                                   # 
  4  #                                                                             # 
  5  # This file is part of the program relax (http://www.nmr-relax.com).          # 
  6  #                                                                             # 
  7  # This program is free software: you can redistribute it and/or modify        # 
  8  # it under the terms of the GNU General Public License as published by        # 
  9  # the Free Software Foundation, either version 3 of the License, or           # 
 10  # (at your option) any later version.                                         # 
 11  #                                                                             # 
 12  # This program is distributed in the hope that it will be useful,             # 
 13  # but WITHOUT ANY WARRANTY; without even the implied warranty of              # 
 14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               # 
 15  # GNU General Public License for more details.                                # 
 16  #                                                                             # 
 17  # You should have received a copy of the GNU General Public License           # 
 18  # along with this program.  If not, see <http://www.gnu.org/licenses/>.       # 
 19  #                                                                             # 
 20  ############################################################################### 
 21   
 22  # Module docstring. 
 23  """The interatomic data containers of the relax data store.""" 
 24   
 25  # Python module imports. 
 26  from re import match 
 27   
 28  # relax module imports. 
 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   
35 -class InteratomContainer(Prototype):
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 # Store the spin IDs. 50 self.spin_id1 = spin_id1 51 self.spin_id2 = spin_id2 52 53 # Class variable defaults. 54 self.dipole_pair = False 55 self.select = select
56 57
58 - def __repr__(self):
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 # Intro. 66 text = "Class containing all the interatomic specific data between spins %s and %s.\n\n" % (self.spin_id1, self.spin_id2) 67 68 # Objects. 69 text = text + "\n" 70 text = text + "Objects:\n" 71 for name in dir(self): 72 # Skip the SpinContainer methods. 73 if name in ['is_empty']: 74 continue 75 76 # Skip special objects. 77 if match("^_", name): 78 continue 79 80 # Add the object's attribute to the text string. 81 text += " %s: %s\n" % (name, repr(getattr(self, name))) 82 83 return text
84 85
86 - def is_empty(self):
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 # An object has been added to the container. 94 for name in dir(self): 95 # Skip the objects initialised in __init__(). 96 if name in ['dipole_pair', 'spin_id1', 'spin_id2', 'select']: 97 continue 98 99 # Skip the SpinContainer methods. 100 if name in ['is_empty']: 101 continue 102 103 # Skip special objects. 104 if match("^_", name): 105 continue 106 107 # An object has been added. 108 return False 109 110 # The SpinContainer is unmodified. 111 return True
112 113 114
115 -class InteratomList(list):
116 """List type data container for interatomic specific data.""" 117
118 - def __repr__(self):
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 # Intro. 125 text = "Interatomic data.\n\n" 126 127 # The data. 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 # Append a new InteratomContainer. 147 cont = InteratomContainer(spin_id1, spin_id2) 148 self.append(cont) 149 150 # Return the container. 151 return cont
152 153
154 - def is_empty(self):
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 # There are no InteratomContainers. 162 if len(self) == 0: 163 return True 164 165 # Otherwise. 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 # Test if empty. 179 if not self.is_empty(): 180 raise RelaxFromXMLNotEmptyError(self.__class__.__name__) 181 182 # Loop over the containers. 183 for interatom_node in interatom_nodes: 184 # Get the interatomic spin details and add a container to the InteratomList structure. 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 # Recreate the current container. 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 # The specific analysis API object. 205 api = specific_analyses.api.return_api(analysis_type=pipe_type) 206 207 # Loop over the containers. 208 for i in range(len(self)): 209 # Create an XML element for this container and add it to the higher level element. 210 interatom_element = doc.createElement('interatomic') 211 element.appendChild(interatom_element) 212 213 # Set the spin attributes. 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 # Get the specific object names and loop over them to get their descriptions. 219 object_info = [] 220 try: 221 for name in api.data_names(error_names=True, sim_names=True): 222 # Get the description. 223 if hasattr(api, 'return_data_desc'): 224 desc = api.return_data_desc(name) 225 else: 226 desc = None 227 228 # Append the two. 229 object_info.append([name, desc]) 230 except RelaxImplementError: 231 pass 232 233 # Add the ordered objects. 234 blacklist = [] 235 for name, desc in object_info: 236 # Add the name to the blacklist. 237 blacklist.append(name) 238 239 # Skip the object if it is missing from the InteratomContainer. 240 if not hasattr(self[i], name): 241 continue 242 243 # Create a new element for this object, and add it to the main element. 244 sub_element = doc.createElement(name) 245 interatom_element.appendChild(sub_element) 246 247 # Add the object description. 248 if desc: 249 sub_element.setAttribute('desc', desc) 250 251 # Get the object. 252 object = getattr(self[i], name) 253 254 # Convert to XML. 255 object_to_xml(doc, sub_element, value=object) 256 257 # Add all simple python objects within the InteratomContainer to the XML element. 258 fill_object_contents(doc, interatom_element, object=self[i], blacklist=['spin_id1', 'spin_id2'] + blacklist + list(self[i].__class__.__dict__.keys()))
259