Package lib :: Package structure :: Package internal :: Module models
[hide private]
[frames] | no frames]

Source Code for Module lib.structure.internal.models

  1  0############################################################################## 
  2  #                                                                             # 
  3  # Copyright (C) 2008-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 objects representing models in the internal structural object.""" 
 24   
 25  # Python module imports. 
 26  from re import match 
 27   
 28  # relax module import. 
 29  from lib.errors import RelaxError, RelaxFromXMLNotEmptyError 
 30  from lib.structure.internal.molecules import MolList 
 31  from lib.xml import fill_object_contents 
 32   
 33   
34 -class ModelList(list):
35 """List type data container for the different structural models. 36 37 Here different models are defined as the same molecule but with different conformations. 38 """ 39
40 - def __init__(self):
41 """Set up the class.""" 42 43 # Execute the base class method. 44 super(ModelList, self).__init__() 45 46 # The current model list (used for speed). 47 self.current_models = []
48 49
50 - def __repr__(self):
51 """The string representation of the object. 52 53 Rather than using the standard Python conventions (either the string representation of the 54 value or the "<...desc...>" notation), a rich-formatted description of the object is given. 55 """ 56 57 text = "Models.\n\n" 58 text = text + "%-8s%-8s" % ("Index", "Model number") + "\n" 59 for i in range(len(self)): 60 text = text + "%-8i%-8s" % (i, self[i].num) + "\n" 61 return text
62 63
64 - def add_item(self, model_num=None):
65 """Append an empty ModelContainer to the ModelList. 66 67 @keyword model_num: The model number. 68 @type model_num: int 69 @return: The model container. 70 @rtype: ModelContainer instance 71 """ 72 73 # If no model data exists, replace the empty first model with this model (just a renumbering). 74 if len(self) and self.is_empty(): 75 self[0].num = model_num 76 77 # Otherwise append an empty ModelContainer. 78 else: 79 # Test if the model number already exists. 80 if model_num in self.current_models: 81 raise RelaxError("The model '" + repr(model_num) + "' already exists.") 82 83 # Append an empty ModelContainer. 84 self.append(ModelContainer(model_num)) 85 86 # Update the current model list. 87 self.current_models.append(model_num) 88 89 # Return the model container. 90 return self[-1]
91 92
93 - def delete_model(self, model_num=None):
94 """Delete the given model from the list. 95 96 @keyword model_num: The model to delete. 97 @type model_num: int 98 """ 99 100 # Sanity check. 101 if model_num not in self.current_models: 102 raise RelaxError("The model %s does not exist." % model_num) 103 104 # Remove the model from the lists (self and the current models). 105 index = self.current_models.index(model_num) 106 self.pop(index) 107 self.current_models.pop(index)
108 109
110 - def is_empty(self):
111 """Method for testing if this ModelList object is empty. 112 113 @return: True if this list only has one ModelContainer and the model name has not 114 been set, False otherwise. 115 @rtype: bool 116 """ 117 118 # No ModelContainers. 119 if len(self) == 0: 120 return True 121 122 # There is only one ModelContainer and it is empty. 123 if len(self) == 1 and self[0].is_empty(): 124 return True 125 126 # Otherwise. 127 return False
128 129
130 - def from_xml(self, model_nodes, file_version=1):
131 """Recreate a model list data structure from the XML model nodes. 132 133 @param model_nodes: The model XML nodes. 134 @type model_nodes: xml.dom.minicompat.NodeList instance 135 @keyword file_version: The relax XML version of the XML file. 136 @type file_version: int 137 """ 138 139 # Test if empty. 140 if not self.is_empty(): 141 raise RelaxFromXMLNotEmptyError(self.__class__.__name__) 142 143 # Loop over the models. 144 for model_node in model_nodes: 145 # Get the model details and add the model to the ModelList structure. 146 num = eval(model_node.getAttribute('num')) 147 if num == 'None': 148 num = None 149 self.add_item(model_num=num) 150 151 # Get the molecule nodes. 152 mol_nodes = model_node.getElementsByTagName('mol_cont') 153 154 # Recreate the molecule data structures for the current model. 155 self[-1].mol.from_xml(mol_nodes, file_version=file_version)
156 157
158 - def to_xml(self, doc, element):
159 """Create XML elements for each model. 160 161 @param doc: The XML document object. 162 @type doc: xml.dom.minidom.Document instance 163 @param element: The element to add the model XML elements to. 164 @type element: XML element object 165 """ 166 167 # Loop over the models. 168 for i in range(len(self)): 169 # Create an XML element for this model and add it to the higher level element. 170 model_element = doc.createElement('model') 171 element.appendChild(model_element) 172 173 # Set the model attributes. 174 model_element.setAttribute('desc', 'Model container') 175 model_element.setAttribute('num', str(self[i].num)) 176 177 # Add all simple python objects within the ModelContainer to the XML element. 178 fill_object_contents(doc, model_element, object=self[i], blacklist=['num', 'mol'] + list(self[i].__class__.__dict__.keys())) 179 180 # Add the molecule data. 181 self[i].mol.to_xml(doc, model_element)
182 183 184
185 -class ModelContainer(object):
186 """Class containing all the model specific data.""" 187
188 - def __init__(self, model_num=None):
189 """Set up the default objects of the model data container.""" 190 191 # The model number. 192 self.num = model_num 193 194 # The empty molecule list. 195 self.mol = MolList()
196 197
198 - def __repr__(self):
199 """The string representation of the object. 200 201 Rather than using the standard Python conventions (either the string representation of the 202 value or the "<...desc...>" notation), a rich-formatted description of the object is given. 203 """ 204 205 # Intro. 206 text = "Class containing the data for model %s.\n" % self.num 207 208 # Objects. 209 text = text + "\n" 210 text = text + "Objects:\n" 211 for name in dir(self): 212 # Molecule list. 213 if name == 'mol': 214 text = text + " mol: The list of %s molecules within the model.\n" % len(self.mol) 215 continue 216 217 # Skip the ModelContainer methods. 218 if name == 'is_empty': 219 continue 220 221 # Skip special objects. 222 if match("^__", name): 223 continue 224 225 # Add the object's attribute to the text string. 226 text = text + " " + name + ": " + repr(getattr(self, name)) + "\n" 227 228 return text
229 230
231 - def is_empty(self):
232 """Method for testing if this ModelContainer object is empty. 233 234 @return: True if this container is empty and the model number has not been set, False 235 otherwise. 236 @rtype: bool 237 """ 238 239 # The model num has been set. 240 if self.num != None: 241 return False 242 243 # An object has been added to the container. 244 for name in dir(self): 245 # Skip the objects initialised in __init__(). 246 if name == 'num' or name == 'mol': 247 continue 248 249 # Skip the ModelContainer methods. 250 if name == 'is_empty': 251 continue 252 253 # Skip special objects. 254 if match("^__", name): 255 continue 256 257 # An object has been added. 258 return False 259 260 # The molecule list is not empty. 261 if not self.mol.is_empty(): 262 return False 263 264 # The ModelContainer is unmodified. 265 return True
266 267
268 - def mol_loop(self):
269 """Generator method to loop over the molecules of this model. 270 271 @return: The molecules of this model. 272 @rtype: MolContainer instance 273 """ 274 275 # Loop over all molecules. 276 for mol in self.mol: 277 # No data, so do not yield the molecule. 278 if mol.is_empty(): 279 continue 280 281 # Yield the molecule. 282 yield mol
283