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