Package Bio :: Package PDB :: Module Entity
[hide private]
[frames] | no frames]

Source Code for Module Bio.PDB.Entity

  1  # Copyright (C) 2002, Thomas Hamelryck (thamelry@binf.ku.dk) 
  2  # This code is part of the Biopython distribution and governed by its 
  3  # license.  Please see the LICENSE file that should have been included 
  4  # as part of this package.   
  5   
  6  from copy import copy 
  7   
  8  from Bio.PDB.PDBExceptions import PDBConstructionException, PDBException 
  9   
 10  """Base class for Residue, Chain, Model and Structure classes. 
 11   
 12  It is a simple container class, with list and dictionary like properties. 
 13  """ 
 14   
 15   
16 -class Entity(object):
17 """ 18 Basic container object. Structure, Model, Chain and Residue 19 are subclasses of Entity. It deals with storage and lookup. 20 """
21 - def __init__(self, id):
22 self.id=id 23 self.full_id=None 24 self.parent=None 25 self.child_list=[] 26 self.child_dict={} 27 # Dictionary that keeps addictional properties 28 self.xtra={}
29 30 # Special methods 31
32 - def __len__(self):
33 "Return the number of children." 34 return len(self.child_list)
35
36 - def __getitem__(self, id):
37 "Return the child with given id." 38 return self.child_dict[id]
39
40 - def __delitem__(self, id):
41 "Remove a child." 42 return self.detach_child(id)
43
44 - def __iter__(self):
45 "Iterate over children." 46 for child in self.child_list: 47 yield child
48 49 # Public methods 50
51 - def get_level(self):
52 """Return level in hierarchy. 53 54 A - atom 55 R - residue 56 C - chain 57 M - model 58 S - structure 59 """ 60 return self.level
61
62 - def set_parent(self, entity):
63 "Set the parent Entity object." 64 self.parent=entity
65
66 - def detach_parent(self):
67 "Detach the parent." 68 self.parent=None
69
70 - def detach_child(self, id):
71 "Remove a child." 72 child=self.child_dict[id] 73 child.detach_parent() 74 del self.child_dict[id] 75 self.child_list.remove(child)
76
77 - def add(self, entity):
78 "Add a child to the Entity." 79 entity_id=entity.get_id() 80 if self.has_id(entity_id): 81 raise PDBConstructionException( \ 82 "%s defined twice" % str(entity_id)) 83 entity.set_parent(self) 84 self.child_list.append(entity) 85 self.child_dict[entity_id]=entity
86
87 - def insert(self, pos, entity):
88 "Add a child to the Entity at a specified position." 89 entity_id=entity.get_id() 90 if self.has_id(entity_id): 91 raise PDBConstructionException( \ 92 "%s defined twice" % str(entity_id)) 93 entity.set_parent(self) 94 self.child_list[pos:pos] = [entity] 95 self.child_dict[entity_id]=entity
96
97 - def get_iterator(self):
98 "Return iterator over children." 99 for child in self.child_list: 100 yield child
101
102 - def get_list(self):
103 "Return a copy of the list of children." 104 return copy(self.child_list)
105
106 - def has_id(self, id):
107 """True if a child with given id exists.""" 108 return (id in self.child_dict)
109
110 - def get_parent(self):
111 "Return the parent Entity object." 112 return self.parent
113
114 - def get_id(self):
115 "Return the id." 116 return self.id
117
118 - def get_full_id(self):
119 """Return the full id. 120 121 The full id is a tuple containing all id's starting from 122 the top object (Structure) down to the current object. A full id for 123 a Residue object e.g. is something like: 124 125 ("1abc", 0, "A", (" ", 10, "A")) 126 127 This corresponds to: 128 129 Structure with id "1abc" 130 Model with id 0 131 Chain with id "A" 132 Residue with id (" ", 10, "A") 133 134 The Residue id indicates that the residue is not a hetero-residue 135 (or a water) beacuse it has a blank hetero field, that its sequence 136 identifier is 10 and its insertion code "A". 137 """ 138 if self.full_id==None: 139 entity_id=self.get_id() 140 l=[entity_id] 141 parent=self.get_parent() 142 while not (parent is None): 143 entity_id=parent.get_id() 144 l.append(entity_id) 145 parent=parent.get_parent() 146 l.reverse() 147 self.full_id=tuple(l) 148 return self.full_id
149
150 - def transform(self, rot, tran):
151 """ 152 Apply rotation and translation to the atomic coordinates. 153 154 Example: 155 >>> rotation=rotmat(pi, Vector(1,0,0)) 156 >>> translation=array((0,0,1), 'f') 157 >>> entity.transform(rotation, translation) 158 159 @param rot: A right multiplying rotation matrix 160 @type rot: 3x3 Numeric array 161 162 @param tran: the translation vector 163 @type tran: size 3 Numeric array 164 """ 165 for o in self.get_list(): 166 o.transform(rot, tran)
167
168 - def copy(self):
169 shallow = copy(self) 170 shallow.child_list = copy(self.child_list) 171 shallow.child_dict = copy(self.child_dict) 172 shallow.xtra = copy(self.xtra) 173 shallow.detach_parent() 174 for index, child in self.child_dict.items(): 175 shallow.detach_child(index) 176 shallow.add(child.copy()) 177 return shallow
178 179
180 -class DisorderedEntityWrapper(object):
181 """ 182 This class is a simple wrapper class that groups a number of equivalent 183 Entities and forwards all method calls to one of them (the currently selected 184 object). DisorderedResidue and DisorderedAtom are subclasses of this class. 185 186 E.g.: A DisorderedAtom object contains a number of Atom objects, 187 where each Atom object represents a specific position of a disordered 188 atom in the structure. 189 """
190 - def __init__(self, id):
191 self.id=id 192 self.child_dict={} 193 self.selected_child=None 194 self.parent=None
195 196 # Special methods 197
198 - def __getattr__(self, method):
199 "Forward the method call to the selected child." 200 if not hasattr(self, 'selected_child'): 201 # Avoid problems with pickling 202 # Unpickling goes into infinite loop! 203 raise AttributeError 204 return getattr(self.selected_child, method)
205
206 - def __getitem__(self, id):
207 "Return the child with the given id." 208 return self.selected_child[id]
209 210 # XXX Why doesn't this forward to selected_child? 211 # (NB: setitem was here before getitem, iter, len, sub)
212 - def __setitem__(self, id, child):
213 "Add a child, associated with a certain id." 214 self.child_dict[id]=child
215
216 - def __iter__(self):
217 "Return the number of children." 218 return iter(self.selected_child)
219
220 - def __len__(self):
221 "Return the number of children." 222 return len(self.selected_child)
223
224 - def __sub__(self, other):
225 """Subtraction with another object.""" 226 return self.selected_child - other
227 228 # Public methods 229
230 - def get_id(self):
231 "Return the id." 232 return self.id
233
234 - def disordered_has_id(self, id):
235 """True if there is an object present associated with this id.""" 236 return (id in self.child_dict)
237
238 - def detach_parent(self):
239 "Detach the parent" 240 self.parent=None 241 for child in self.disordered_get_list(): 242 child.detach_parent()
243
244 - def get_parent(self):
245 "Return parent." 246 return self.parent
247
248 - def set_parent(self, parent):
249 "Set the parent for the object and its children." 250 self.parent=parent 251 for child in self.disordered_get_list(): 252 child.set_parent(parent)
253
254 - def disordered_select(self, id):
255 """Select the object with given id as the currently active object. 256 257 Uncaught method calls are forwarded to the selected child object. 258 """ 259 self.selected_child=self.child_dict[id]
260
261 - def disordered_add(self, child):
262 "This is implemented by DisorderedAtom and DisorderedResidue." 263 raise NotImplementedError
264
265 - def is_disordered(self):
266 """ 267 Return 2, indicating that this Entity is a collection of Entities. 268 """ 269 return 2
270
271 - def disordered_get_id_list(self):
272 "Return a list of id's." 273 l=self.child_dict.keys() 274 # sort id list alphabetically 275 l.sort() 276 return l
277
278 - def disordered_get(self, id=None):
279 """Get the child object associated with id. 280 281 If id is None, the currently selected child is returned. 282 """ 283 if id==None: 284 return self.selected_child 285 return self.child_dict[id]
286
287 - def disordered_get_list(self):
288 "Return list of children." 289 return self.child_dict.values()
290