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

Source Code for Module Bio.PDB.Atom

  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  """Atom class, used in Structure objects.""" 
  7   
  8  import numpy 
  9  import warnings 
 10  import copy 
 11   
 12  from Bio.PDB.Entity import DisorderedEntityWrapper 
 13  from Bio.PDB.PDBExceptions import PDBConstructionWarning 
 14  from Bio.PDB.Vector import Vector 
 15  from Bio.Data import IUPACData 
 16   
 17   
18 -class Atom(object):
19 - def __init__(self, name, coord, bfactor, occupancy, altloc, fullname, serial_number, 20 element=None):
21 """ 22 Atom object. 23 24 The Atom object stores atom name (both with and without spaces), 25 coordinates, B factor, occupancy, alternative location specifier 26 and (optionally) anisotropic B factor and standard deviations of 27 B factor and positions. 28 29 @param name: atom name (eg. "CA"). Note that spaces are normally stripped. 30 @type name: string 31 32 @param coord: atomic coordinates (x,y,z) 33 @type coord: Numeric array (Float0, size 3) 34 35 @param bfactor: isotropic B factor 36 @type bfactor: number 37 38 @param occupancy: occupancy (0.0-1.0) 39 @type occupancy: number 40 41 @param altloc: alternative location specifier for disordered atoms 42 @type altloc: string 43 44 @param fullname: full atom name, including spaces, e.g. " CA ". Normally 45 these spaces are stripped from the atom name. 46 @type fullname: string 47 48 @param element: atom element, e.g. "C" for Carbon, "HG" for mercury, 49 @type fullname: uppercase string (or None if unknown) 50 """ 51 self.level="A" 52 # Reference to the residue 53 self.parent=None 54 # the atomic data 55 self.name=name # eg. CA, spaces are removed from atom name 56 self.fullname=fullname # e.g. " CA ", spaces included 57 self.coord=coord 58 self.bfactor=bfactor 59 self.occupancy=occupancy 60 self.altloc=altloc 61 self.full_id=None # (structure id, model id, chain id, residue id, atom id) 62 self.id=name # id of atom is the atom name (e.g. "CA") 63 self.disordered_flag=0 64 self.anisou_array=None 65 self.siguij_array=None 66 self.sigatm_array=None 67 self.serial_number=serial_number 68 # Dictionary that keeps additional properties 69 self.xtra={} 70 assert not element or element == element.upper(), element 71 self.element = self._assign_element(element) 72 self.mass = self._assign_atom_mass()
73
74 - def _assign_element(self, element):
75 """Tries to guess element from atom name if not recognised.""" 76 if not element or element.capitalize() not in IUPACData.atom_weights: 77 # Inorganic elements have their name shifted left by one position 78 # (is a convention in PDB, but not part of the standard). 79 # isdigit() check on last two characters to avoid mis-assignment of 80 # hydrogens atoms (GLN HE21 for example) 81 82 if self.fullname[0].isalpha() and not self.fullname[2:].isdigit(): 83 putative_element = self.name.strip() 84 else: 85 # Hs may have digit in [0] 86 if self.name[0].isdigit(): 87 putative_element = self.name[1] 88 else: 89 putative_element = self.name[0] 90 91 if putative_element.capitalize() in IUPACData.atom_weights: 92 msg = "Used element %r for Atom (name=%s) with given element %r" \ 93 % (putative_element, self.name, element) 94 element = putative_element 95 else: 96 msg = "Could not assign element %r for Atom (name=%s) with given element %r" \ 97 % (putative_element, self.name, element) 98 element = "" 99 warnings.warn(msg, PDBConstructionWarning) 100 101 return element
102
103 - def _assign_atom_mass(self):
104 # Needed for Bio/Struct/Geometry.py C.O.M. function 105 if self.element: 106 return IUPACData.atom_weights[self.element.capitalize()] 107 else: 108 return float('NaN')
109 110 # Special methods 111
112 - def __repr__(self):
113 "Print Atom object as <Atom atom_name>." 114 return "<Atom %s>" % self.get_id()
115
116 - def __sub__(self, other):
117 """ 118 Calculate distance between two atoms. 119 120 Example: 121 >>> distance=atom1-atom2 122 123 @param other: the other atom 124 @type other: L{Atom} 125 """ 126 diff=self.coord-other.coord 127 return numpy.sqrt(numpy.dot(diff, diff))
128 129 # set methods 130
131 - def set_serial_number(self, n):
132 self.serial_number=n
133
134 - def set_bfactor(self, bfactor):
135 self.bfactor=bfactor
136
137 - def set_coord(self, coord):
138 self.coord=coord
139
140 - def set_altloc(self, altloc):
141 self.altloc=altloc
142
143 - def set_occupancy(self, occupancy):
144 self.occupancy=occupancy
145
146 - def set_sigatm(self, sigatm_array):
147 """ 148 Set standard deviation of atomic parameters. 149 150 The standard deviation of atomic parameters consists 151 of 3 positional, 1 B factor and 1 occupancy standard 152 deviation. 153 154 @param sigatm_array: standard deviations of atomic parameters. 155 @type sigatm_array: Numeric array (length 5) 156 """ 157 self.sigatm_array=sigatm_array
158
159 - def set_siguij(self, siguij_array):
160 """ 161 Set standard deviations of anisotropic temperature factors. 162 163 @param siguij_array: standard deviations of anisotropic temperature factors. 164 @type siguij_array: Numeric array (length 6) 165 """ 166 self.siguij_array=siguij_array
167
168 - def set_anisou(self, anisou_array):
169 """ 170 Set anisotropic B factor. 171 172 @param anisou_array: anisotropic B factor. 173 @type anisou_array: Numeric array (length 6) 174 """ 175 self.anisou_array=anisou_array
176 177 # Public methods 178
179 - def flag_disorder(self):
180 """Set the disordered flag to 1. 181 182 The disordered flag indicates whether the atom is disordered or not. 183 """ 184 self.disordered_flag=1
185
186 - def is_disordered(self):
187 "Return the disordered flag (1 if disordered, 0 otherwise)." 188 return self.disordered_flag
189
190 - def set_parent(self, parent):
191 """Set the parent residue. 192 193 Arguments: 194 o parent - Residue object 195 """ 196 self.parent=parent
197
198 - def detach_parent(self):
199 "Remove reference to parent." 200 self.parent=None
201
202 - def get_sigatm(self):
203 "Return standard deviation of atomic parameters." 204 return self.sigatm_array
205
206 - def get_siguij(self):
207 "Return standard deviations of anisotropic temperature factors." 208 return self.siguij_array
209
210 - def get_anisou(self):
211 "Return anisotropic B factor." 212 return self.anisou_array
213
214 - def get_parent(self):
215 "Return parent residue." 216 return self.parent
217
218 - def get_serial_number(self):
219 return self.serial_number
220
221 - def get_name(self):
222 "Return atom name." 223 return self.name
224
225 - def get_id(self):
226 "Return the id of the atom (which is its atom name)." 227 return self.id
228
229 - def get_full_id(self):
230 """Return the full id of the atom. 231 232 The full id of an atom is the tuple 233 (structure id, model id, chain id, residue id, atom name, altloc). 234 """ 235 return self.parent.get_full_id()+((self.name, self.altloc),)
236
237 - def get_coord(self):
238 "Return atomic coordinates." 239 return self.coord
240
241 - def get_bfactor(self):
242 "Return B factor." 243 return self.bfactor
244
245 - def get_occupancy(self):
246 "Return occupancy." 247 return self.occupancy
248
249 - def get_fullname(self):
250 "Return the atom name, including leading and trailing spaces." 251 return self.fullname
252
253 - def get_altloc(self):
254 "Return alternative location specifier." 255 return self.altloc
256
257 - def get_level(self):
258 return self.level
259
260 - def transform(self, rot, tran):
261 """ 262 Apply rotation and translation to the atomic coordinates. 263 264 Example: 265 >>> rotation=rotmat(pi, Vector(1, 0, 0)) 266 >>> translation=array((0, 0, 1), 'f') 267 >>> atom.transform(rotation, translation) 268 269 @param rot: A right multiplying rotation matrix 270 @type rot: 3x3 Numeric array 271 272 @param tran: the translation vector 273 @type tran: size 3 Numeric array 274 """ 275 self.coord=numpy.dot(self.coord, rot)+tran
276
277 - def get_vector(self):
278 """ 279 Return coordinates as Vector. 280 281 @return: coordinates as 3D vector 282 @rtype: Vector 283 """ 284 x, y, z=self.coord 285 return Vector(x, y, z)
286
287 - def copy(self):
288 """ 289 Create a copy of the Atom. 290 Parent information is lost. 291 """ 292 # Do a shallow copy then explicitly copy what needs to be deeper. 293 shallow = copy.copy(self) 294 shallow.detach_parent() 295 shallow.set_coord(copy.copy(self.get_coord())) 296 shallow.xtra = self.xtra.copy() 297 return shallow
298 299
300 -class DisorderedAtom(DisorderedEntityWrapper):
301 """ 302 This class contains all Atom objects that represent the same disordered 303 atom. One of these atoms is "selected" and all method calls not caught 304 by DisorderedAtom are forwarded to the selected Atom object. In that way, a 305 DisorderedAtom behaves exactly like a normal Atom. By default, the selected 306 Atom object represents the Atom object with the highest occupancy, but a 307 different Atom object can be selected by using the disordered_select(altloc) 308 method. 309 """
310 - def __init__(self, id):
311 """ 312 Arguments: 313 o id - string, atom name 314 """ 315 self.last_occupancy=-1 316 DisorderedEntityWrapper.__init__(self, id)
317 318 # Special methods 319
320 - def __repr__(self):
321 return "<Disordered Atom %s>" % self.get_id()
322
323 - def disordered_add(self, atom):
324 "Add a disordered atom." 325 # Add atom to dict, use altloc as key 326 atom.flag_disorder() 327 # set the residue parent of the added atom 328 residue=self.get_parent() 329 atom.set_parent(residue) 330 altloc=atom.get_altloc() 331 occupancy=atom.get_occupancy() 332 self[altloc]=atom 333 if occupancy>self.last_occupancy: 334 self.last_occupancy=occupancy 335 self.disordered_select(altloc)
336