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

Source Code for Module Bio.PDB.StructureBuilder

  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  __doc__=""" 
  7  Consumer class that builds a Structure object. This is used by  
  8  the PDBParser and MMCIFparser classes. 
  9  """ 
 10   
 11  import warnings 
 12   
 13  # My stuff  
 14  # SMCRA hierarchy 
 15  from Structure import Structure 
 16  from Model import Model 
 17  from Chain import Chain 
 18  from Residue import Residue, DisorderedResidue 
 19  from Atom import Atom, DisorderedAtom  
 20   
 21  from PDBExceptions import PDBConstructionException, PDBConstructionWarning 
 22   
 23   
24 -class StructureBuilder:
25 """ 26 Deals with contructing the Structure object. The StructureBuilder class is used 27 by the PDBParser classes to translate a file to a Structure object. 28 """
29 - def __init__(self):
30 self.line_counter=0 31 self.header={}
32
33 - def _is_completely_disordered(self, residue):
34 "Return 1 if all atoms in the residue have a non blank altloc." 35 atom_list=residue.get_unpacked_list() 36 for atom in atom_list: 37 altloc=atom.get_altloc() 38 if altloc==" ": 39 return 0 40 return 1
41 42 # Public methods called by the Parser classes 43
44 - def set_header(self, header):
45 self.header=header
46
47 - def set_line_counter(self, line_counter):
48 """ 49 The line counter keeps track of the line in the PDB file that 50 is being parsed. 51 52 Arguments: 53 o line_counter - int 54 """ 55 self.line_counter=line_counter
56
57 - def init_structure(self, structure_id):
58 """Initiate a new Structure object with given id. 59 60 Arguments: 61 o id - string 62 """ 63 self.structure=Structure(structure_id)
64
65 - def init_model(self, model_id):
66 """Initiate a new Model object with given id. 67 68 Arguments: 69 o id - int 70 """ 71 self.model=Model(model_id) 72 self.structure.add(self.model)
73
74 - def init_chain(self, chain_id):
75 """Initiate a new Chain object with given id. 76 77 Arguments: 78 o chain_id - string 79 """ 80 if self.model.has_id(chain_id): 81 self.chain=self.model[chain_id] 82 if __debug__: 83 warnings.warn("WARNING: Chain %s is discontinuous at line %i." 84 % (chain_id, self.line_counter), 85 PDBConstructionWarning) 86 else: 87 self.chain=Chain(chain_id) 88 self.model.add(self.chain)
89
90 - def init_seg(self, segid):
91 """Flag a change in segid. 92 93 Arguments: 94 o segid - string 95 """ 96 self.segid=segid
97
98 - def init_residue(self, resname, field, resseq, icode):
99 """ 100 Initiate a new Residue object. 101 102 Arguments: 103 o resname - string, e.g. "ASN" 104 o field - hetero flag, "W" for waters, "H" for 105 hetero residues, otherwise blank. 106 o resseq - int, sequence identifier 107 o icode - string, insertion code 108 """ 109 if field!=" ": 110 if field=="H": 111 # The hetero field consists of H_ + the residue name (e.g. H_FUC) 112 field="H_"+resname 113 res_id=(field, resseq, icode) 114 if field==" ": 115 if self.chain.has_id(res_id): 116 # There already is a residue with the id (field, resseq, icode). 117 # This only makes sense in the case of a point mutation. 118 if __debug__: 119 warnings.warn("WARNING: Residue ('%s', %i, '%s') " 120 "redefined at line %i." 121 % (field, resseq, icode, self.line_counter), 122 PDBConstructionWarning) 123 duplicate_residue=self.chain[res_id] 124 if duplicate_residue.is_disordered()==2: 125 # The residue in the chain is a DisorderedResidue object. 126 # So just add the last Residue object. 127 if duplicate_residue.disordered_has_id(resname): 128 # The residue was already made 129 self.residue=duplicate_residue 130 duplicate_residue.disordered_select(resname) 131 else: 132 # Make a new residue and add it to the already 133 # present DisorderedResidue 134 new_residue=Residue(res_id, resname, self.segid) 135 duplicate_residue.disordered_add(new_residue) 136 self.residue=duplicate_residue 137 return 138 else: 139 # Make a new DisorderedResidue object and put all 140 # the Residue objects with the id (field, resseq, icode) in it. 141 # These residues each should have non-blank altlocs for all their atoms. 142 # If not, the PDB file probably contains an error. 143 if not self._is_completely_disordered(duplicate_residue): 144 # if this exception is ignored, a residue will be missing 145 self.residue=None 146 raise PDBConstructionException(\ 147 "Blank altlocs in duplicate residue %s ('%s', %i, '%s')" \ 148 % (resname, field, resseq, icode)) 149 self.chain.detach_child(res_id) 150 new_residue=Residue(res_id, resname, self.segid) 151 disordered_residue=DisorderedResidue(res_id) 152 self.chain.add(disordered_residue) 153 disordered_residue.disordered_add(duplicate_residue) 154 disordered_residue.disordered_add(new_residue) 155 self.residue=disordered_residue 156 return 157 residue=Residue(res_id, resname, self.segid) 158 self.chain.add(residue) 159 self.residue=residue
160
161 - def init_atom(self, name, coord, b_factor, occupancy, altloc, fullname, serial_number=None):
162 """ 163 Initiate a new Atom object. 164 165 Arguments: 166 o name - string, atom name, e.g. CA, spaces should be stripped 167 o coord - Numeric array (Float0, size 3), atomic coordinates 168 o b_factor - float, B factor 169 o occupancy - float 170 o altloc - string, alternative location specifier 171 o fullname - string, atom name including spaces, e.g. " CA " 172 """ 173 residue=self.residue 174 # if residue is None, an exception was generated during 175 # the construction of the residue 176 if residue is None: 177 return 178 # First check if this atom is already present in the residue. 179 # If it is, it might be due to the fact that the two atoms have atom 180 # names that differ only in spaces (e.g. "CA.." and ".CA.", 181 # where the dots are spaces). If that is so, use all spaces 182 # in the atom name of the current atom. 183 if residue.has_id(name): 184 duplicate_atom=residue[name] 185 # atom name with spaces of duplicate atom 186 duplicate_fullname=duplicate_atom.get_fullname() 187 if duplicate_fullname!=fullname: 188 # name of current atom now includes spaces 189 name=fullname 190 if __debug__: 191 warnings.warn("WARNING: atom names %s and %s differ " 192 "only in spaces at line %i." 193 % (duplicate_fullname, fullname, 194 self.line_counter), 195 PDBConstructionWarning) 196 atom=self.atom=Atom(name, coord, b_factor, occupancy, altloc, fullname, serial_number) 197 if altloc!=" ": 198 # The atom is disordered 199 if residue.has_id(name): 200 # Residue already contains this atom 201 duplicate_atom=residue[name] 202 if duplicate_atom.is_disordered()==2: 203 duplicate_atom.disordered_add(atom) 204 else: 205 # This is an error in the PDB file: 206 # a disordered atom is found with a blank altloc 207 # Detach the duplicate atom, and put it in a 208 # DisorderedAtom object together with the current 209 # atom. 210 residue.detach_child(name) 211 disordered_atom=DisorderedAtom(name) 212 residue.add(disordered_atom) 213 disordered_atom.disordered_add(atom) 214 disordered_atom.disordered_add(duplicate_atom) 215 residue.flag_disordered() 216 if __debug__: 217 warnings.warn("WARNING: disordered atom found " 218 "with blank altloc before line %i.\n" 219 % self.line_counter, 220 PDBConstructionWarning) 221 else: 222 # The residue does not contain this disordered atom 223 # so we create a new one. 224 disordered_atom=DisorderedAtom(name) 225 residue.add(disordered_atom) 226 # Add the real atom to the disordered atom, and the 227 # disordered atom to the residue 228 disordered_atom.disordered_add(atom) 229 residue.flag_disordered() 230 else: 231 # The atom is not disordered 232 residue.add(atom)
233
234 - def set_anisou(self, anisou_array):
235 "Set anisotropic B factor of current Atom." 236 self.atom.set_anisou(anisou_array)
237
238 - def set_siguij(self, siguij_array):
239 "Set standard deviation of anisotropic B factor of current Atom." 240 self.atom.set_siguij(siguij_array)
241
242 - def set_sigatm(self, sigatm_array):
243 "Set standard deviation of atom position of current Atom." 244 self.atom.set_sigatm(sigatm_array)
245
246 - def get_structure(self):
247 "Return the structure." 248 # first sort everything 249 # self.structure.sort() 250 # Add the header dict 251 self.structure.header=self.header 252 return self.structure
253
254 - def set_symmetry(self, spacegroup, cell):
255 pass
256